shithub: aacdec

Download patch

ref: 4ec9a8f39dbd88813601b448ec07849bac4caa6b
parent: 9596ecdf5d384c896dbb32e13eb9d3856b9d09f8
author: menno <menno>
date: Wed Jul 9 11:11:25 EDT 2003

WAVE_FORMAT_EXTENSIBLE output

--- a/frontend/audio.c
+++ b/frontend/audio.c
@@ -16,7 +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.
 **
-** $Id: audio.c,v 1.15 2003/07/09 11:53:07 menno Exp $
+** $Id: audio.c,v 1.16 2003/07/09 15:11:25 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -31,7 +31,7 @@
 
 
 audio_file *open_audio_file(char *infile, int samplerate, int channels,
-                            int outputFormat, int fileType)
+                            int outputFormat, int fileType, long channelMask)
 {
     audio_file *aufile = malloc(sizeof(audio_file));
 
@@ -41,6 +41,7 @@
     aufile->channels = channels;
     aufile->total_samples = 0;
     aufile->fileType = fileType;
+    aufile->channelMask = channelMask;
 
     switch (outputFormat)
     {
@@ -79,7 +80,10 @@
 
     if (aufile->fileType == OUTPUT_WAV)
     {
-        write_wav_header(aufile);
+        if (aufile->channelMask)
+            write_wav_extensible_header(aufile, aufile->channelMask);
+        else
+            write_wav_header(aufile);
     }
 
     return aufile;
@@ -114,7 +118,10 @@
     {
         fseek(aufile->sndfile, 0, SEEK_SET);
 
-        write_wav_header(aufile);
+        if (aufile->channelMask)
+            write_wav_extensible_header(aufile, aufile->channelMask);
+        else
+            write_wav_header(aufile);
     }
 
     fclose(aufile->sndfile);
@@ -186,10 +193,9 @@
     return fwrite(header, sizeof(header), 1, aufile->sndfile);
 }
 
-/* ??????? */
 static int write_wav_extensible_header(audio_file *aufile, long channelMask)
 {
-    unsigned char header[66];
+    unsigned char header[68];
     unsigned char* p = header;
     unsigned int bytes = (aufile->bits_per_sample + 7) / 8;
     float data_size = (float)bytes * aufile->total_samples;
@@ -197,8 +203,8 @@
 
     *p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F';
 
-    word32 = (data_size + (66 - 8) < (float)MAXWAVESIZE) ?
-        (unsigned long)data_size + (66 - 8)  :  (unsigned long)MAXWAVESIZE;
+    word32 = (data_size + (68 - 8) < (float)MAXWAVESIZE) ?
+        (unsigned long)data_size + (68 - 8)  :  (unsigned long)MAXWAVESIZE;
     *p++ = (unsigned char)(word32 >>  0);
     *p++ = (unsigned char)(word32 >>  8);
     *p++ = (unsigned char)(word32 >> 16);
@@ -208,7 +214,7 @@
 
     *p++ = 'f'; *p++ = 'm'; *p++ = 't'; *p++ = ' ';
 
-    *p++ = 0x10; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
+    *p++ = /*0x10*/0x28; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
 
     /* WAVE_FORMAT_EXTENSIBLE */
     *p++ = 0xFE; *p++ = 0xFF;
@@ -256,18 +262,18 @@
     if (aufile->outputFormat == FAAD_FMT_FLOAT)
     {
         /* KSDATAFORMAT_SUBTYPE_IEEE_FLOAT: 00000003-0000-0010-8000-00aa00389b71 */
-//        /*??*/ *p++ = 0x00;
-//        /*??*/ *p++ = 0x00;
         *p++ = 0x03;
         *p++ = 0x00;
+        *p++ = 0x00;
+        *p++ = 0x00;
         *p++ = 0x00; *p++ = 0x00; *p++ = 0x10; *p++ = 0x00; *p++ = 0x80; *p++ = 0x00;
         *p++ = 0x00; *p++ = 0xaa; *p++ = 0x00; *p++ = 0x38; *p++ = 0x9b; *p++ = 0x71;
     } else {
         /* KSDATAFORMAT_SUBTYPE_PCM: 00000001-0000-0010-8000-00aa00389b71 */
-//        /*??*/ *p++ = 0x00;
-//        /*??*/ *p++ = 0x00;
         *p++ = 0x01;
         *p++ = 0x00;
+        *p++ = 0x00;
+        *p++ = 0x00;
         *p++ = 0x00; *p++ = 0x00; *p++ = 0x10; *p++ = 0x00; *p++ = 0x80; *p++ = 0x00;
         *p++ = 0x00; *p++ = 0xaa; *p++ = 0x00; *p++ = 0x38; *p++ = 0x9b; *p++ = 0x71;
     }
@@ -296,6 +302,26 @@
 
     aufile->total_samples += samples;
 
+    if (aufile->channels == 6 && aufile->channelMask)
+    {
+        for (i = 0; i < samples; i += aufile->channels)
+        {
+            short r1, r2, r3, r4, r5, r6;
+            r1 = sample_buffer16[i];
+            r2 = sample_buffer16[i+1];
+            r3 = sample_buffer16[i+2];
+            r4 = sample_buffer16[i+3];
+            r5 = sample_buffer16[i+4];
+            r6 = sample_buffer16[i+5];
+            sample_buffer16[i] = r2;
+            sample_buffer16[i+1] = r3;
+            sample_buffer16[i+2] = r1;
+            sample_buffer16[i+3] = r6;
+            sample_buffer16[i+4] = r4;
+            sample_buffer16[i+5] = r5;
+        }
+    }
+
     for (i = 0; i < samples; i++)
     {
         data[i*2] = (char)(sample_buffer16[i] & 0xFF);
@@ -319,6 +345,26 @@
 
     aufile->total_samples += samples;
 
+    if (aufile->channels == 6 && aufile->channelMask)
+    {
+        for (i = 0; i < samples; i += aufile->channels)
+        {
+            long r1, r2, r3, r4, r5, r6;
+            r1 = sample_buffer24[i];
+            r2 = sample_buffer24[i+1];
+            r3 = sample_buffer24[i+2];
+            r4 = sample_buffer24[i+3];
+            r5 = sample_buffer24[i+4];
+            r6 = sample_buffer24[i+5];
+            sample_buffer24[i] = r2;
+            sample_buffer24[i+1] = r3;
+            sample_buffer24[i+2] = r1;
+            sample_buffer24[i+3] = r6;
+            sample_buffer24[i+4] = r4;
+            sample_buffer24[i+5] = r5;
+        }
+    }
+
     for (i = 0; i < samples; i++)
     {
         data[i*3] = (char)(sample_buffer24[i] & 0xFF);
@@ -343,6 +389,26 @@
 
     aufile->total_samples += samples;
 
+    if (aufile->channels == 6 && aufile->channelMask)
+    {
+        for (i = 0; i < samples; i += aufile->channels)
+        {
+            long r1, r2, r3, r4, r5, r6;
+            r1 = sample_buffer32[i];
+            r2 = sample_buffer32[i+1];
+            r3 = sample_buffer32[i+2];
+            r4 = sample_buffer32[i+3];
+            r5 = sample_buffer32[i+4];
+            r6 = sample_buffer32[i+5];
+            sample_buffer32[i] = r2;
+            sample_buffer32[i+1] = r3;
+            sample_buffer32[i+2] = r1;
+            sample_buffer32[i+3] = r6;
+            sample_buffer32[i+4] = r4;
+            sample_buffer32[i+5] = r5;
+        }
+    }
+
     for (i = 0; i < samples; i++)
     {
         data[i*4] = (char)(sample_buffer32[i] & 0xFF);
@@ -367,6 +433,26 @@
     unsigned char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
 
     aufile->total_samples += samples;
+
+    if (aufile->channels == 6 && aufile->channelMask)
+    {
+        for (i = 0; i < samples; i += aufile->channels)
+        {
+            float r1, r2, r3, r4, r5, r6;
+            r1 = sample_buffer_f[i];
+            r2 = sample_buffer_f[i+1];
+            r3 = sample_buffer_f[i+2];
+            r4 = sample_buffer_f[i+3];
+            r5 = sample_buffer_f[i+4];
+            r6 = sample_buffer_f[i+5];
+            sample_buffer_f[i] = r2;
+            sample_buffer_f[i+1] = r3;
+            sample_buffer_f[i+2] = r1;
+            sample_buffer_f[i+3] = r6;
+            sample_buffer_f[i+4] = r4;
+            sample_buffer_f[i+5] = r5;
+        }
+    }
 
     for (i = 0; i < samples; i++)
     {
--- a/frontend/audio.h
+++ b/frontend/audio.h
@@ -16,7 +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.
 **
-** $Id: audio.h,v 1.7 2003/07/08 13:45:45 menno Exp $
+** $Id: audio.h,v 1.8 2003/07/09 15:11:25 menno Exp $
 **/
 
 #ifndef AUDIO_H_INCLUDED
@@ -40,13 +40,15 @@
     unsigned int bits_per_sample;
     unsigned int channels;
     unsigned long total_samples;
+    long channelMask;
 } audio_file;
 
 audio_file *open_audio_file(char *infile, int samplerate, int channels,
-                            int outputFormat, int fileType);
+                            int outputFormat, int fileType, long channelMask);
 int write_audio_file(audio_file *aufile, void *sample_buffer, int samples);
 void close_audio_file(audio_file *aufile);
 static int write_wav_header(audio_file *aufile);
+static int write_wav_extensible_header(audio_file *aufile, long channelMask);
 static int write_audio_16bit(audio_file *aufile, void *sample_buffer,
                              unsigned int samples);
 static int write_audio_24bit(audio_file *aufile, void *sample_buffer,
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -16,7 +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.
 **
-** $Id: main.c,v 1.40 2003/07/09 13:55:59 menno Exp $
+** $Id: main.c,v 1.41 2003/07/09 15:11:25 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -155,6 +155,39 @@
     return 1;
 }
 
+/* MicroSoft channel definitions */
+#define SPEAKER_FRONT_LEFT             0x1
+#define SPEAKER_FRONT_RIGHT            0x2
+#define SPEAKER_FRONT_CENTER           0x4
+#define SPEAKER_LOW_FREQUENCY          0x8
+#define SPEAKER_BACK_LEFT              0x10
+#define SPEAKER_BACK_RIGHT             0x20
+#define SPEAKER_FRONT_LEFT_OF_CENTER   0x40
+#define SPEAKER_FRONT_RIGHT_OF_CENTER  0x80
+#define SPEAKER_BACK_CENTER            0x100
+#define SPEAKER_SIDE_LEFT              0x200
+#define SPEAKER_SIDE_RIGHT             0x400
+#define SPEAKER_TOP_CENTER             0x800
+#define SPEAKER_TOP_FRONT_LEFT         0x1000
+#define SPEAKER_TOP_FRONT_CENTER       0x2000
+#define SPEAKER_TOP_FRONT_RIGHT        0x4000
+#define SPEAKER_TOP_BACK_LEFT          0x8000
+#define SPEAKER_TOP_BACK_CENTER        0x10000
+#define SPEAKER_TOP_BACK_RIGHT         0x20000
+#define SPEAKER_RESERVED               0x80000000
+
+long aacChannelConfig2wavexChannelMask(faacDecFrameInfo *hInfo)
+{
+    if (hInfo->channels == 6 && hInfo->num_lfe_channels)
+    {
+        return SPEAKER_FRONT_LEFT + SPEAKER_FRONT_RIGHT +
+            SPEAKER_FRONT_CENTER + SPEAKER_LOW_FREQUENCY +
+            SPEAKER_BACK_LEFT + SPEAKER_BACK_RIGHT;
+    } else {
+        return 0;
+    }
+}
+
 char *position2string(int position)
 {
     switch (position)
@@ -179,15 +212,24 @@
 {
     /* print some channel info */
     int i;
+    long channelMask = aacChannelConfig2wavexChannelMask(frameInfo);
 
     printf("  ---------------------\n");
     if (frameInfo->num_lfe_channels > 0)
     {
-        printf(" | Config: %2d.%d Ch     |\n", frameInfo->channels-frameInfo->num_lfe_channels, frameInfo->num_lfe_channels);
+        printf(" | Config: %2d.%d Ch     |", frameInfo->channels-frameInfo->num_lfe_channels, frameInfo->num_lfe_channels);
     } else {
-        printf(" | Config: %2d Ch       |\n", frameInfo->channels);
+        printf(" | Config: %2d Ch       |", frameInfo->channels);
     }
-    printf("  ---------------------\n");
+    if (channelMask)
+        printf(" WARNING: channels are reordered according to\n");
+    else
+        printf("\n");
+    printf("  ---------------------");
+    if (channelMask)
+        printf("  MS defaults defined in WAVE_FORMAT_EXTENSIBLE\n");
+    else
+        printf("\n");
     printf(" | Ch |    Position    |\n");
     printf("  ---------------------\n");
     for (i = 0; i < frameInfo->channels; i++)
@@ -198,6 +240,7 @@
     printf("\n");
 }
 
+
 /* globals */
 char *progName;
 
@@ -428,10 +471,10 @@
             if (!to_stdout)
             {
                 aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
-                    outputFormat, fileType);
+                    outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
             } else {
                 aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
-                    outputFormat, fileType);
+                    outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
             }
             if (aufile == NULL)
             {
@@ -649,13 +692,13 @@
             if(!to_stdout)
             {
                 aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
-                    outputFormat, fileType);
+                    outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
             } else {
 #ifdef _WIN32
                 setmode(fileno(stdout), O_BINARY);
 #endif
                 aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
-                    outputFormat, fileType);
+                    outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
             }
             if (aufile == NULL)
             {