changeset 2360:ead24454f4b7

native 24bit output for FLAC
author Eugene Zagidullin <e.asphyx@gmail.com>
date Tue, 05 Feb 2008 07:37:00 +0300
parents b3475063c000
children c831816c0b87 2b561aa49580
files src/flacng/flacng.h src/flacng/plugin.c src/flacng/seekable_stream_callbacks.c
diffstat 3 files changed, 33 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/src/flacng/flacng.h	Mon Feb 04 23:12:46 2008 +0300
+++ b/src/flacng/flacng.h	Tue Feb 05 07:37:00 2008 +0300
@@ -30,6 +30,9 @@
 #define BUFFER_SIZE_SAMP (FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS)
 #define BUFFER_SIZE_BYTE (BUFFER_SIZE_SAMP * (FLAC__MAX_BITS_PER_SAMPLE/8))
 
+#define SAMPLE_SIZE(a) (a == 8 ? sizeof(guint8) : (a == 16 ? sizeof(guint16) : sizeof(guint32)))
+#define SAMPLE_FMT(a) (a == 8 ? FMT_S8 : (a == 16 ? FMT_S16_NE : (a == 24 ? FMT_S24_NE : FMT_S32_NE)))
+
 /*
  * Audio information about the stream as a whole, gathered from
  * the metadata header
--- a/src/flacng/plugin.c	Mon Feb 04 23:12:46 2008 +0300
+++ b/src/flacng/plugin.c	Tue Feb 05 07:37:00 2008 +0300
@@ -16,6 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
+/* #define FLACNG_DEBUG */
 
 #include "flacng.h"
 #include <audacious/util.h>
@@ -216,9 +217,10 @@
         _LEAVE FALSE;
     }
 
-    if ((16 != test_info->stream.bits_per_sample) &&
+    if ((8  != test_info->stream.bits_per_sample) &&
+        (16 != test_info->stream.bits_per_sample) &&
         (24 != test_info->stream.bits_per_sample) &&
-        (8 != test_info->stream.bits_per_sample)) {
+        (32 != test_info->stream.bits_per_sample)) {
         _ERROR("This number of bits (%d) is currently not supported, stream not handled by this plugin",
             test_info->stream.bits_per_sample);
         INFO_UNLOCK(test_info);
@@ -264,12 +266,7 @@
 
 /* --- */
 
-void squeeze_audio(gint32* src, void* dst, guint count, guint src_res, guint dst_res) {
-
-    /*
-     * Changes the sample width of count samples in src from
-     * src_res to dst_res and places the result in dst
-     */
+void squeeze_audio(gint32* src, void* dst, guint count, guint res) {
 
     gint i;
     gint32* rp = src;
@@ -279,68 +276,25 @@
 
     _ENTER;
 
-    _DEBUG("Converting %d samples %d->%d", count, src_res, dst_res);
+    _DEBUG("Converting %d samples to %d bit", count, res);
 
-    if ((src_res % 8 != 0) || (dst_res % 8 != 0)) {
-        _ERROR("Can not convert from %d bps to %d bps: not a multiple of 8",
-                src_res, dst_res);
+    if (res % 8 != 0) {
+        _ERROR("Can not convert to %d bps: not a multiple of 8", res);
         _LEAVE;
     }
 
-    if (16 == dst_res) {
-        if (8 == src_res) {
-            for (i=0; i<count; i++, wp2++, rp++) {
-                *wp2 = (*rp << 8) & 0xffff;
-            }
-        } else if (16 == src_res) {
-            for (i=0; i<count; i++, wp2++, rp++) {
-                *wp2 = *rp & 0xffff;
-            }
-        } else if (24 == src_res) {
-            for (i=0; i<count; i++, wp2++, rp++) {
-                *wp2 = (*rp >> 8) & 0xffff;
-            }
-        } else if (32 == src_res) {
-            for (i=0; i<count; i++, wp2++, rp++) {
-                *wp2 = (*rp >> 16) & 0xffff;
-            }
+    if (res == 8) {
+        for (i=0; i<count; i++, wp++, rp++) {
+            *wp = *rp & 0xff;
         }
-    } else if (8 == dst_res) {
-        if (8 == src_res) {
-            for (i=0; i<count; i++, wp++, rp++) {
-                *wp = *rp & 0xff;
-            }
-        } else if (16 == src_res) {
-            for (i=0; i<count; i++, wp++, rp++) {
-                *wp = (*rp >> 8) & 0xff;
-            }
-        } else if (24 == src_res) {
-            for (i=0; i<count; i++, wp++, rp++) {
-                *wp = (*rp >> 16) & 0xff;
-            }
-        } else if (32 == src_res) {
-            for (i=0; i<count; i++, wp++, rp++) {
-                *wp = (*rp >> 24) & 0xff;
-            }
+    } else if (res == 16) {
+        for (i=0; i<count; i++, wp2++, rp++) {
+            *wp2 = *rp & 0xffff;
         }
-    } else if (32 == dst_res) {
-        if (8 == src_res) {
-            for (i=0; i<count; i++, wp4++, rp++) {
-                *wp4 = (*rp << 24) & 0xffffffff;
-            }
-        } else if (16 == src_res) {
-            for (i=0; i<count; i++, wp4++, rp++) {
-                *wp4 = (*rp << 16) & 0xffffffff;
-            }
-        } else if (24 == src_res) {
-            for (i=0; i<count; i++, wp4++, rp++) {
-                *wp4 = (*rp << 8) & 0xffffffff;
-            }
-        } else if (32 == src_res) {
-            for (i=0; i<count; i++, wp4++, rp++) {
-                *wp4 = *rp;
-            }
-        }
+    } else if (res == 24 || res == 32) { /* 24bit value stored in lowest 3 bytes */
+       for (i=0; i<count; i++, wp4++, rp++) {
+           *wp4 = *rp;
+       }
     }
 
     _LEAVE;
@@ -377,9 +331,9 @@
     stream_info.channels = main_info->stream.channels;
     main_info->metadata_changed = FALSE;
 
-    if (!playback->output->open_audio(FMT_S16_NE,
-        main_info->stream.samplerate,
-        main_info->stream.channels)) {
+    if (!playback->output->open_audio(SAMPLE_FMT(main_info->stream.bits_per_sample),
+                                      main_info->stream.samplerate,
+                                      main_info->stream.channels)) {
         playback->playing = FALSE;
         _ERROR("Could not open output plugin!");
         _LEAVE NULL;
@@ -454,17 +408,16 @@
 
             sample_count = MIN(OUTPUT_BLOCK_SIZE, elements_left);
 
-            /*
-             * Convert the audio.
-             * Currently this is hardcoded to 16 bit.
-             * 8 and 24 bit are sampled up/down linear.
-             */
-            _DEBUG("Converting %d samples to FMT_S16_NE", sample_count);
-            squeeze_audio(read_pointer, play_buffer, sample_count, main_info->frame.bits_per_sample, 16);
+            squeeze_audio(read_pointer, play_buffer, sample_count, main_info->stream.bits_per_sample);
 
             _DEBUG("Copying %d samples to output plugin", sample_count);
 
-            playback->pass_audio(playback, FMT_S16_NE, main_info->frame.channels, sample_count * sizeof(gint16), play_buffer, NULL);
+            playback->pass_audio(playback,
+                                 SAMPLE_FMT(main_info->stream.bits_per_sample),
+                                 main_info->stream.channels,
+                                 sample_count * SAMPLE_SIZE(main_info->stream.bits_per_sample),
+                                 play_buffer,
+                                 NULL);
 
             read_pointer += sample_count;
             elements_left -= sample_count;
--- a/src/flacng/seekable_stream_callbacks.c	Mon Feb 04 23:12:46 2008 +0300
+++ b/src/flacng/seekable_stream_callbacks.c	Tue Feb 05 07:37:00 2008 +0300
@@ -209,7 +209,8 @@
 
     if ((frame->header.bits_per_sample != 8) &&
         (frame->header.bits_per_sample != 16) &&
-        (frame->header.bits_per_sample != 24)) {
+        (frame->header.bits_per_sample != 24) &&
+        (frame->header.bits_per_sample != 32)) {
         _ERROR("Unsupported bitrate found in stream: %d!", frame->header.bits_per_sample);
         _LEAVE FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
     }