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)
{