Merge "Add support for reading 8-bit PCM"
diff --git a/audio_utils/Android.mk b/audio_utils/Android.mk
index b653f5a..e1102e5 100644
--- a/audio_utils/Android.mk
+++ b/audio_utils/Android.mk
@@ -33,4 +33,6 @@
LOCAL_C_INCLUDES += \
$(call include-path-for, audio-utils)
+LOCAL_SHARED_LIBRARIES := libaudioutils
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/audio_utils/include/audio_utils/sndfile.h b/audio_utils/include/audio_utils/sndfile.h
index eff7067..1d12ae5 100644
--- a/audio_utils/include/audio_utils/sndfile.h
+++ b/audio_utils/include/audio_utils/sndfile.h
@@ -24,9 +24,15 @@
// no guarantee that it will stay exactly source-code compatible with other libraries.
#include <stdio.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
// visible to clients
+typedef int sf_count_t;
+
typedef struct {
+ sf_count_t frames;
int samplerate;
int channels;
int format;
@@ -35,8 +41,6 @@
// opaque to clients
typedef struct SNDFILE_ SNDFILE;
-typedef unsigned sf_count_t;
-
// Access modes
#define SFM_READ 1
@@ -54,6 +58,8 @@
void sf_close(SNDFILE *handle);
// Read interleaved frames and return actual number of frames read
-ssize_t sf_readf_short(SNDFILE *handle, short *ptr, size_t desired);
+sf_count_t sf_readf_short(SNDFILE *handle, short *ptr, sf_count_t desired);
+
+__END_DECLS
#endif /* __AUDIO_UTIL_SNDFILE_H */
diff --git a/audio_utils/tinysndfile.c b/audio_utils/tinysndfile.c
index b50ad72..f028685 100644
--- a/audio_utils/tinysndfile.c
+++ b/audio_utils/tinysndfile.c
@@ -15,6 +15,7 @@
*/
#include <audio_utils/sndfile.h>
+#include <audio_utils/primitives.h>
#include <stdio.h>
#include <string.h>
@@ -86,7 +87,7 @@
// ignore byte rate
// ignore block alignment
unsigned bitsPerSample = little2u(&wav[34]);
- if (/*bitsPerSample != 8 &&*/ bitsPerSample != 16)
+ if (bitsPerSample != 8 && bitsPerSample != 16)
break;
unsigned bytesPerFrame = (bitsPerSample >> 3) * channels;
if (memcmp(&wav[36], "data", 4))
@@ -96,9 +97,14 @@
handle->stream = stream;
handle->bytesPerFrame = bytesPerFrame;
handle->remaining = dataSize / bytesPerFrame;
+ handle->info.frames = handle->remaining;
handle->info.samplerate = samplerate;
handle->info.channels = channels;
- handle->info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+ handle->info.format = SF_FORMAT_WAV;
+ if (bitsPerSample == 8)
+ handle->info.format |= SF_FORMAT_PCM_U8;
+ else
+ handle->info.format |= SF_FORMAT_PCM_16;
*info = handle->info;
return handle;
}
@@ -114,18 +120,25 @@
handle->remaining = 0;
}
-ssize_t sf_readf_short(SNDFILE *handle, short *ptr, size_t desiredFrames)
+sf_count_t sf_readf_short(SNDFILE *handle, short *ptr, sf_count_t desiredFrames)
{
- if (handle == NULL || ptr == NULL || !handle->remaining)
+ if (handle == NULL || ptr == NULL || !handle->remaining || desiredFrames <= 0)
return 0;
- if (handle->remaining < desiredFrames)
+ if (handle->remaining < (size_t) desiredFrames)
desiredFrames = handle->remaining;
size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
// does not check for numeric overflow
size_t actualBytes = fread(ptr, sizeof(char), desiredBytes, handle->stream);
size_t actualFrames = actualBytes / handle->bytesPerFrame;
handle->remaining -= actualFrames;
- if (!isLittleEndian())
- swab(ptr, actualFrames * handle->info.channels);
+ switch (handle->info.format & SF_FORMAT_SUBMASK) {
+ case SF_FORMAT_PCM_U8:
+ memcpy_to_i16_from_u8(ptr, (unsigned char *) ptr, actualFrames * handle->info.channels);
+ break;
+ case SF_FORMAT_PCM_16:
+ if (!isLittleEndian())
+ swab(ptr, actualFrames * handle->info.channels);
+ break;
+ }
return actualFrames;
}