aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-03-02 16:39:54 +0100
committerMax Kellermann <max@duempel.org>2009-03-02 16:39:54 +0100
commitd4e4c57b8d5bb583628b5d4ddf36ec022a61768c (patch)
tree83fa03e1f429ed5690cf9d811c389756bcc47b0a /src
parentd24f2ba5ee91657b834daf9592a2b9c29d6e5847 (diff)
downloadmpd-d4e4c57b8d5bb583628b5d4ddf36ec022a61768c.tar.gz
mpd-d4e4c57b8d5bb583628b5d4ddf36ec022a61768c.tar.xz
mpd-d4e4c57b8d5bb583628b5d4ddf36ec022a61768c.zip
pcm_format: added pcm_convert_to_32()
Added code to convert all other sample formats to 32 bit.
Diffstat (limited to 'src')
-rw-r--r--src/pcm_format.c75
-rw-r--r--src/pcm_format.h15
2 files changed, 90 insertions, 0 deletions
diff --git a/src/pcm_format.c b/src/pcm_format.c
index 205966a6e..9ef1a9504 100644
--- a/src/pcm_format.c
+++ b/src/pcm_format.c
@@ -133,3 +133,78 @@ pcm_convert_to_24(struct pcm_buffer *buffer,
g_warning("only 8 or 24 bits are supported for conversion!\n");
return NULL;
}
+
+static void
+pcm_convert_8_to_32(int32_t *out, const int8_t *in,
+ unsigned num_samples)
+{
+ while (num_samples > 0) {
+ *out++ = *in++ << 24;
+ --num_samples;
+ }
+}
+
+static void
+pcm_convert_16_to_32(int32_t *out, const int16_t *in,
+ unsigned num_samples)
+{
+ while (num_samples > 0) {
+ *out++ = *in++ << 16;
+ --num_samples;
+ }
+}
+
+static void
+pcm_convert_24_to_32(int32_t *out, const int32_t *in,
+ unsigned num_samples)
+{
+ while (num_samples > 0) {
+ *out++ = *in++ << 8;
+ --num_samples;
+ }
+}
+
+const int32_t *
+pcm_convert_to_32(struct pcm_buffer *buffer,
+ uint8_t bits, const void *src,
+ size_t src_size, size_t *dest_size_r)
+{
+ unsigned num_samples;
+ int32_t *dest;
+
+ switch (bits) {
+ case 8:
+ num_samples = src_size;
+ *dest_size_r = src_size * sizeof(*dest);
+ dest = pcm_buffer_get(buffer, *dest_size_r);
+
+ pcm_convert_8_to_32(dest, (const int8_t *)src,
+ num_samples);
+ return dest;
+
+ case 16:
+ num_samples = src_size / 2;
+ *dest_size_r = num_samples * sizeof(*dest);
+ dest = pcm_buffer_get(buffer, *dest_size_r);
+
+ pcm_convert_16_to_32(dest, (const int16_t *)src,
+ num_samples);
+ return dest;
+
+ case 24:
+ num_samples = src_size / 4;
+ *dest_size_r = num_samples * sizeof(*dest);
+ dest = pcm_buffer_get(buffer, *dest_size_r);
+
+ pcm_convert_24_to_32(dest, (const int32_t *)src,
+ num_samples);
+ return dest;
+
+ case 32:
+ *dest_size_r = src_size;
+ return src;
+ }
+
+ g_warning("only 8 or 32 bits are supported for conversion!\n");
+ return NULL;
+}
diff --git a/src/pcm_format.h b/src/pcm_format.h
index 53547df5d..3da10f2a7 100644
--- a/src/pcm_format.h
+++ b/src/pcm_format.h
@@ -57,4 +57,19 @@ pcm_convert_to_24(struct pcm_buffer *buffer,
uint8_t bits, const void *src,
size_t src_size, size_t *dest_size_r);
+/**
+ * Converts PCM samples to 32 bit.
+ *
+ * @param buffer a pcm_buffer object
+ * @param bits the number of in the source buffer
+ * @param src the source PCM buffer
+ * @param src_size the size of #src in bytes
+ * @param dest_size_r returns the number of bytes of the destination buffer
+ * @return the destination buffer
+ */
+const int32_t *
+pcm_convert_to_32(struct pcm_buffer *buffer,
+ uint8_t bits, const void *src,
+ size_t src_size, size_t *dest_size_r);
+
#endif