ref: c12d8b8c3a448a01865b6b3f15b0452ea67b9a8f
parent: e98a69b9db88ef00994bbc7a95add426a36adcf6
author: menno <menno>
date: Tue Jul 8 09:45:45 EDT 2003
reverted some changes in the frontend better multichannel support
--- 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.13 2003/07/07 21:11:17 menno Exp $
+** $Id: audio.c,v 1.14 2003/07/08 13:45:45 menno Exp $
**/
#ifdef _WIN32
@@ -63,17 +63,13 @@
return NULL;
}
- if(!infile)
+#ifdef _WIN32
+ if(infile[0] == '-')
{
-#ifdef __BORLANDC__
setmode(fileno(stdout), O_BINARY);
-#elif defined _MSC_VER || defined __MINGW32__
- _setmode(_fileno(stdout), _O_BINARY);
-#endif
- aufile->sndfile = stdout;
- } else {
- aufile->sndfile = fopen(infile, "wb");
}
+#endif
+ aufile->sndfile = fopen(infile, "wb");
if (aufile->sndfile == NULL)
{
@@ -84,7 +80,6 @@
if (aufile->fileType == OUTPUT_WAV)
{
write_wav_header(aufile);
- aufile->total_samples = 0;
}
return aufile;
@@ -113,16 +108,17 @@
return 0;
}
-void close_audio_file(audio_file *aufile, char *fileName)
+void close_audio_file(audio_file *aufile)
{
- if (aufile->fileType == OUTPUT_WAV && fileName)
+ if (aufile->fileType == OUTPUT_WAV)
{
fseek(aufile->sndfile, 0, SEEK_SET);
write_wav_header(aufile);
- fclose(aufile->sndfile);
}
+ fclose(aufile->sndfile);
+
if (aufile) free(aufile);
}
@@ -131,13 +127,8 @@
unsigned char header[44];
unsigned char* p = header;
unsigned int bytes = (aufile->bits_per_sample + 7) / 8;
- float data_size;
+ float data_size = (float)bytes * aufile->total_samples;
unsigned long word32;
-
- if (aufile->total_samples)
- data_size = aufile->total_samples * bytes;
- else
- data_size = (float)(long)(0x7fffffff);
*p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F';
--- 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.6 2003/07/07 21:11:17 menno Exp $
+** $Id: audio.h,v 1.7 2003/07/08 13:45:45 menno Exp $
**/
#ifndef AUDIO_H_INCLUDED
@@ -45,7 +45,7 @@
audio_file *open_audio_file(char *infile, int samplerate, int channels,
int outputFormat, int fileType);
int write_audio_file(audio_file *aufile, void *sample_buffer, int samples);
-void close_audio_file(audio_file *aufile, char *fileName);
+void close_audio_file(audio_file *aufile);
static int write_wav_header(audio_file *aufile);
static int write_audio_16bit(audio_file *aufile, void *sample_buffer,
unsigned int samples);
--- a/frontend/faad.dsp
+++ b/frontend/faad.dsp
@@ -97,10 +97,6 @@
SOURCE=.\main.c
# End Source File
-# Begin Source File
-
-SOURCE=.\wave_out.c
-# End Source File
# End Group
# Begin Group "Header Files"
@@ -128,10 +124,6 @@
# Begin Source File
SOURCE=..\common\mp4v2\systems.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\wave_out.h
# End Source File
# Begin Source File
--- 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.37 2003/07/07 21:11:17 menno Exp $
+** $Id: main.c,v 1.38 2003/07/08 13:45:45 menno Exp $
**/
#ifdef _WIN32
@@ -34,17 +34,14 @@
#include <mp4.h>
#include "audio.h"
-#ifdef _WIN32
-#include "wave_out.h"
-#endif
#ifndef min
#define min(a,b) ( (a) < (b) ? (a) : (b) )
#endif
-#define MAX_CHANNELS 8 /* make this higher to support files with
- more channels */
+#define MAX_CHANNELS 6 /* make this higher to support files with
+ more channels */
/* FAAD file buffering routines */
typedef struct {
long bytes_into_buffer;
@@ -201,14 +198,6 @@
fprintf(stdout, " 3: LTP (Long Term Prediction) object type.\n");
fprintf(stdout, " 23: LD (Low Delay) object type.\n");
fprintf(stdout, " -w Write output to stdio instead of a file.\n");
-#ifdef _WIN32
- fprintf(stdout, " -p Plays aac/mp4 files thru the soundcard using Windows audio.\n");
- fprintf(stdout, " Playback Priority Options (ONE option ONLY may be used)\n");
- fprintf(stdout, " -c X Set playback priority class, where X =\n");
- fprintf(stdout, " 0: NORMAL priority.\n");
- fprintf(stdout, " 1: HIGH priority (default).\n");
- fprintf(stdout, " 2: REALTIME priority.\n");
-#endif
fprintf(stdout, "Example:\n");
fprintf(stdout, " faad infile.aac\n");
fprintf(stdout, " faad infile.mp4\n");
@@ -219,7 +208,7 @@
int decodeAACfile(char *aacfile, char *sndfile, int to_stdout,
int def_srate, int object_type, int outputFormat, int fileType,
- int infoOnly, int playback, unsigned int play_priority)
+ int infoOnly)
{
int tagsize;
unsigned long samplerate;
@@ -400,49 +389,28 @@
/* open the sound file now that the number of channels are known */
if (first_time && !frameInfo.error)
{
- if(to_stdout)
- sndfile = NULL;
-
- if(playback == 1)
+ if (!to_stdout)
{
-#ifdef _WIN32
- if (Set_WIN_Params(INVALID_FILEDESC, samplerate, SAMPLE_SIZE,
- frameInfo.channels, play_priority) < 0)
- {
- fprintf(stderr, "ERROR: Can't access %s\n", "WAVE OUT");
- if (b.buffer)
- free(b.buffer);
- faacDecClose(hDecoder);
- fclose(b.infile);
- return 0;
- }
-#endif
- } else {
aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
outputFormat, fileType);
-
- if (aufile == NULL)
- {
- if (b.buffer)
- free(b.buffer);
- faacDecClose(hDecoder);
- fclose(b.infile);
- return 0;
- }
+ } else {
+ aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
+ outputFormat, fileType);
}
+ if (aufile == NULL)
+ {
+ if (b.buffer)
+ free(b.buffer);
+ faacDecClose(hDecoder);
+ fclose(b.infile);
+ return 0;
+ }
first_time = 0;
}
if ((frameInfo.error == 0) && (frameInfo.samples > 0))
{
- if(playback == 1)
-#ifdef _WIN32
- WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples);
-#else
- fprintf(stderr, "Playback on anything other than WIN32 not possible.\n");
-#endif
- else
- write_audio_file(aufile, sample_buffer, frameInfo.samples);
+ write_audio_file(aufile, sample_buffer, frameInfo.samples);
}
/* fill buffer */
@@ -458,15 +426,8 @@
fclose(b.infile);
- if (playback == 1)
- {
-#ifdef _WIN32
- WIN_Audio_close();
-#endif
- } else {
- if (!first_time)
- close_audio_file(aufile, sndfile);
- }
+ if (!first_time)
+ close_audio_file(aufile);
if (b.buffer)
free(b.buffer);
@@ -516,8 +477,7 @@
};
int decodeMP4file(char *mp4file, char *sndfile, int to_stdout,
- int outputFormat, int fileType, int infoOnly,
- int playback, unsigned int play_priority)
+ int outputFormat, int fileType, int infoOnly)
{
int track;
unsigned int tracks;
@@ -645,45 +605,29 @@
/* open the sound file now that the number of channels are known */
if (first_time && !frameInfo.error)
{
- if (to_stdout)
- sndfile = NULL;
-
- if(playback == 1)
+ if(!to_stdout)
{
+ aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
+ outputFormat, fileType);
+ } else {
#ifdef _WIN32
- if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE,
- frameInfo.channels, play_priority) < 0)
- {
- fprintf(stderr, "\nCan't access %s\n", "WAVE OUT");
- faacDecClose(hDecoder);
- MP4Close(infile);
- return (0);
- }
+ setmode(fileno(stdout), O_BINARY);
#endif
- } else {
- aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
+ aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
outputFormat, fileType);
-
- if (aufile == NULL)
- {
- faacDecClose(hDecoder);
- MP4Close(infile);
- return 0;
- }
}
+ if (aufile == NULL)
+ {
+ faacDecClose(hDecoder);
+ MP4Close(infile);
+ return 0;
+ }
first_time = 0;
}
if ((frameInfo.error == 0) && (frameInfo.samples > 0))
{
- if (playback == 1)
-#ifdef _WIN32
- WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples);
-#else
- fprintf(stderr, "Playback on anything other than WIN32 not possible.\n");
-#endif
- else
- write_audio_file(aufile, sample_buffer, frameInfo.samples);
+ write_audio_file(aufile, sample_buffer, frameInfo.samples);
}
if (frameInfo.error > 0)
@@ -698,15 +642,8 @@
MP4Close(infile);
- if (playback == 1)
- {
-#ifdef _WIN32
- WIN_Audio_close();
-#endif
- } else {
- if (!first_time)
- close_audio_file(aufile, sndfile);
- }
+ if (!first_time)
+ close_audio_file(aufile);
return frameInfo.error;
}
@@ -722,8 +659,6 @@
int outputFormat = FAAD_FMT_16BIT;
int outfile_set = 0;
int showHelp = 0;
- int playback = 0;
- unsigned int play_priority = 1;
int mp4file = 0;
char *fnp;
char aacFileName[255];
@@ -763,13 +698,11 @@
{ "samplerate", 0, 0, 's' },
{ "objecttype", 0, 0, 'l' },
{ "info", 0, 0, 'i' },
- { "playback", 0, 0, 'p' },
- { "priority", 0, 0, 'c' },
{ "stdio", 0, 0, 'w' },
{ "help", 0, 0, 'h' }
};
- c = getopt_long(argc, argv, "o:s:f:b:l:whipc:",
+ c = getopt_long(argc, argv, "o:s:f:b:l:whi",
long_options, &option_index);
if (c == -1)
@@ -833,27 +766,7 @@
}
}
break;
-#ifdef _WIN32
- case 'p':
- playback = 1;
- break;
- case 'c':
- if (optarg) {
- char dr[10];
- if (sscanf(optarg, "%s", dr) < 1) {
- play_priority = 1; /* default */
- } else {
- play_priority = atoi(dr);
- if(play_priority > 2)
- {
- fprintf(stderr, "Warning: priority class %s not recognised, using default\n", optarg);
- play_priority = 1;
- }
- }
- }
- break;
-#endif
- case 'w':
+ case 'w':
writeToStdio = 1;
break;
case 'i':
@@ -908,11 +821,10 @@
if (mp4file)
{
result = decodeMP4file(aacFileName, audioFileName, writeToStdio,
- outputFormat, format, infoOnly, playback, play_priority);
+ outputFormat, format, infoOnly);
} else {
result = decodeAACfile(aacFileName, audioFileName, writeToStdio,
- def_srate, object_type, outputFormat, format, infoOnly,
- playback, play_priority);
+ def_srate, object_type, outputFormat, format, infoOnly);
}
--- a/frontend/wave_out.c
+++ /dev/null
@@ -1,212 +1,0 @@
-/* Set TABS = 4 */
-/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- ********************************************************************
-
- function: To provide playback of 16 bit PCM wave data in Win32
- environments from decoded aac/mp4 files.
-
- ********************************************************************/
-
-#include <string.h>
-#include <errno.h>
-#include "wave_out.h"
-
-#ifdef _WIN32
-
-#define MAXWAVESIZE 4294967040LU
-#define MAX_WAVEBLOCKS 32
-
-static CRITICAL_SECTION cs;
-static HWAVEOUT dev = NULL;
-static int ScheduledBlocks = 0;
-static int PlayedWaveHeadersCount = 0; // free index
-static WAVEHDR* PlayedWaveHeaders [MAX_WAVEBLOCKS];
-
-static int
-Box ( const char* msg )
-{
- MessageBox ( NULL, msg, " Error Message . . .", MB_OK | MB_ICONEXCLAMATION );
- return -1;
-}
-
-
-/*
- * This function registers already played WAVE chunks. Freeing is done by free_memory(),
- */
-
-static void CALLBACK
-wave_callback ( HWAVE hWave, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
-{
- if ( uMsg == WOM_DONE ) {
- EnterCriticalSection ( &cs );
- PlayedWaveHeaders [PlayedWaveHeadersCount++] = (WAVEHDR*) dwParam1;
- LeaveCriticalSection ( &cs );
- }
-}
-
-
-static void
-free_memory ( void )
-{
- WAVEHDR* wh;
- HGLOBAL hg;
-
- EnterCriticalSection ( &cs );
- wh = PlayedWaveHeaders [--PlayedWaveHeadersCount];
- ScheduledBlocks--; // decrease the number of USED blocks
- LeaveCriticalSection ( &cs );
-
- waveOutUnprepareHeader ( dev, wh, sizeof (WAVEHDR) );
-
- hg = GlobalHandle ( wh -> lpData ); // Deallocate the buffer memory
- GlobalUnlock (hg);
- GlobalFree (hg);
-
- hg = GlobalHandle ( wh ); // Deallocate the header memory
- GlobalUnlock (hg);
- GlobalFree (hg);
-}
-
-
-int
-Set_WIN_Params ( FILE_T dummyFile ,
- long double SampleFreq,
- unsigned int BitsPerSample,
- unsigned int Channels,
- unsigned int play_priority )
-{
- WAVEFORMATEX outFormat;
- UINT deviceID = WAVE_MAPPER;
-
- (void) dummyFile;
-
- if ( waveOutGetNumDevs () == 0 )
- return Box ( "No audio device present." );
-
- outFormat.wFormatTag = WAVE_FORMAT_PCM;
- outFormat.wBitsPerSample = BitsPerSample;
- outFormat.nChannels = Channels;
- outFormat.nSamplesPerSec = (unsigned long)(SampleFreq + 0.5);
- outFormat.nBlockAlign = (outFormat.wBitsPerSample + 7) / 8 * outFormat.nChannels;
- outFormat.nAvgBytesPerSec = outFormat.nSamplesPerSec * outFormat.nBlockAlign;
-
- switch ( waveOutOpen ( &dev, deviceID, &outFormat, (DWORD)wave_callback, 0, CALLBACK_FUNCTION ) )
- {
- case MMSYSERR_ALLOCATED: return Box ( "Device is already open." );
- case MMSYSERR_BADDEVICEID: return Box ( "The specified device is out of range." );
- case MMSYSERR_NODRIVER: return Box ( "There is no audio driver in this system." );
- case MMSYSERR_NOMEM: return Box ( "Unable to allocate sound memory." );
- case WAVERR_BADFORMAT: return Box ( "This audio format is not supported." );
- case WAVERR_SYNC: return Box ( "The device is synchronous." );
- default: return Box ( "Unknown media error." );
- case MMSYSERR_NOERROR: break;
- }
-
- waveOutReset ( dev );
- InitializeCriticalSection ( &cs );
- switch(play_priority)
- {
- case 0:
- SetPriorityClass ( GetCurrentProcess (), NORMAL_PRIORITY_CLASS );
- break;
- case 1:
- SetPriorityClass ( GetCurrentProcess (), HIGH_PRIORITY_CLASS );
- break;
- case 2:
- SetPriorityClass ( GetCurrentProcess (), REALTIME_PRIORITY_CLASS );
- break;
- }
- return 0;
-}
-
-
-int
-WIN_Play_Samples ( const void* data, size_t len )
-{
- HGLOBAL hg;
- HGLOBAL hg2;
- LPWAVEHDR wh;
- void* allocptr;
-
- do {
- while ( PlayedWaveHeadersCount > 0 ) // free used blocks ...
- free_memory ();
-
- if ( ScheduledBlocks < sizeof(PlayedWaveHeaders)/sizeof(*PlayedWaveHeaders) ) // wait for a free block ...
- break;
- Sleep (26);
- } while (1);
-
- if ( (hg2 = GlobalAlloc ( GMEM_MOVEABLE, len )) == NULL ) // allocate some memory for a copy of the buffer
- return Box ( "GlobalAlloc failed." );
-
- allocptr = GlobalLock (hg2);
- CopyMemory ( allocptr, data, len ); // Here we can call any modification output functions we want....
-
- if ( (hg = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (WAVEHDR))) == NULL ) // now make a header and WRITE IT!
- return -1;
-
- wh = GlobalLock (hg);
- wh -> dwBufferLength = len;
- wh -> lpData = allocptr;
-
- if ( waveOutPrepareHeader ( dev, wh, sizeof (WAVEHDR)) != MMSYSERR_NOERROR ) {
- GlobalUnlock (hg);
- GlobalFree (hg);
- return -1;
- }
-
- if ( waveOutWrite ( dev, wh, sizeof (WAVEHDR)) != MMSYSERR_NOERROR ) {
- GlobalUnlock (hg);
- GlobalFree (hg);
- return -1;
- }
-
- EnterCriticalSection ( &cs );
- ScheduledBlocks++;
- LeaveCriticalSection ( &cs );
-
- return len;
-}
-
-
-int
-WIN_Audio_close ( void )
-{
- if ( dev != NULL ) {
-
- while ( ScheduledBlocks > 0 ) {
- Sleep (ScheduledBlocks);
- while ( PlayedWaveHeadersCount > 0 ) // free used blocks ...
- free_memory ();
- }
-
- waveOutReset (dev); // reset the device
- waveOutClose (dev); // close the device
- dev = NULL;
- }
-
- DeleteCriticalSection ( &cs );
- ScheduledBlocks = 0;
- return 0;
-}
-
-#endif
-
-/* end of wave_out.c */
--- a/frontend/wave_out.h
+++ /dev/null
@@ -1,45 +1,0 @@
-/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-// WAVE_OUT.H - Necessary stuff for WIN_AUDIO
-
-#include <stdio.h>
-#include <windows.h>
-
-#define Cdecl __cdecl
-#define __attribute__(x)
-#define sleep(__sec) Sleep ((__sec) * 1000)
-#define inline __inline
-#define restrict
-
-//// constants /////////////////////////////////////////////////////
-
-#define CD_SAMPLE_FREQ 44.1e3
-#define SAMPLE_SIZE 16
-#define SAMPLE_SIZE_STRING ""
-#define WINAUDIO_FD ((FILE_T)-128)
-#define FILE_T FILE*
-#define INVALID_FILEDESC NULL
-
-//// procedures/functions //////////////////////////////////////////
-// wave_out.c
-int Set_WIN_Params ( FILE_T dummyFile , long double SampleFreq, unsigned int BitsPerSample, unsigned int Channels, unsigned int play_priority );
-int WIN_Play_Samples ( const void* buff, size_t len );
-int WIN_Audio_close ( void );
-
--- a/include/faad.h
+++ b/include/faad.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: faad.h,v 1.22 2003/07/07 21:11:18 menno Exp $
+** $Id: faad.h,v 1.23 2003/07/08 13:45:45 menno Exp $
**/
#ifndef __AACDEC_H__
@@ -47,7 +47,7 @@
#define ER_LC 17
#define ER_LTP 19
#define LD 23
-#define DRM_ER_LC 32 /* special object type for DRM */
+#define DRM_ER_LC 27 /* special object type for DRM */
/* header types */
#define RAW 0
@@ -129,7 +129,11 @@
unsigned long samplerate;
/* multichannel configuration */
- unsigned char channel_config[64];
+ unsigned char num_front_channels;
+ unsigned char num_side_channels;
+ unsigned char num_back_channels;
+ unsigned char num_lfe_channels;
+ unsigned char channel_position[64];
} faacDecFrameInfo;
char* FAADAPI faacDecGetErrorMessage(unsigned char errcode);
--- a/libfaad/bits.h
+++ b/libfaad/bits.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: bits.h,v 1.18 2003/07/07 21:11:18 menno Exp $
+** $Id: bits.h,v 1.19 2003/07/08 13:45:45 menno Exp $
**/
#ifndef __BITS_H__
@@ -162,7 +162,7 @@
return (uint8_t)faad_getbits(ld, 1 DEBUGVAR(print,var,dbg));
ld->bits_left--;
- r = (uint8_t)((ld->bufa >> ld->bits_left) & 1);
+ r = (ld->bufa >> ld->bits_left) & 1;
return r;
}
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.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: decoder.c,v 1.58 2003/07/07 21:11:18 menno Exp $
+** $Id: decoder.c,v 1.59 2003/07/08 13:45:45 menno Exp $
**/
#include "common.h"
@@ -367,6 +367,130 @@
if (hDecoder) free(hDecoder);
}
+void create_channel_config(faacDecHandle hDecoder, faacDecFrameInfo *hInfo)
+{
+ hInfo->num_front_channels = 0;
+ hInfo->num_side_channels = 0;
+ hInfo->num_back_channels = 0;
+ hInfo->num_lfe_channels = 0;
+ memset(hInfo->channel_position, 0, MAX_CHANNELS*sizeof(uint8_t));
+
+ /* check if there is a PCE */
+ if (hDecoder->pce_set)
+ {
+ uint8_t i, chpos = 0;
+ uint8_t chdir, back_center = 0;
+
+ hInfo->num_front_channels = hDecoder->pce.num_front_channels;
+ hInfo->num_side_channels = hDecoder->pce.num_side_channels;
+ hInfo->num_back_channels = hDecoder->pce.num_back_channels;
+ hInfo->num_lfe_channels = hDecoder->pce.num_lfe_channels;
+
+ chdir = hInfo->num_front_channels;
+ if (chdir & 1)
+ {
+ hInfo->channel_position[chpos++] = FRONT_CHANNEL_CENTER;
+ chdir--;
+ }
+ for (i = 0; i < chdir; i += 2)
+ {
+ hInfo->channel_position[chpos++] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[chpos++] = FRONT_CHANNEL_RIGHT;
+ }
+
+ for (i = 0; i < hInfo->num_side_channels; i += 2)
+ {
+ hInfo->channel_position[chpos++] = SIDE_CHANNEL_LEFT;
+ hInfo->channel_position[chpos++] = SIDE_CHANNEL_RIGHT;
+ }
+
+ chdir = hInfo->num_back_channels;
+ if (chdir & 1)
+ {
+ back_center = 1;
+ chdir--;
+ }
+ for (i = 0; i < chdir; i += 2)
+ {
+ hInfo->channel_position[chpos++] = BACK_CHANNEL_LEFT;
+ hInfo->channel_position[chpos++] = BACK_CHANNEL_RIGHT;
+ }
+ if (back_center)
+ {
+ hInfo->channel_position[chpos++] = BACK_CHANNEL_CENTER;
+ }
+
+ for (i = 0; i < hInfo->num_lfe_channels; i++)
+ {
+ hInfo->channel_position[chpos++] = LFE_CHANNEL;
+ }
+
+ } else {
+ switch (hDecoder->channelConfiguration)
+ {
+ case 1:
+ hInfo->num_front_channels = 1;
+ hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+ break;
+ case 2:
+ hInfo->num_front_channels = 2;
+ hInfo->channel_position[0] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT;
+ break;
+ case 3:
+ hInfo->num_front_channels = 3;
+ hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+ hInfo->channel_position[1] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT;
+ break;
+ case 4:
+ hInfo->num_front_channels = 3;
+ hInfo->num_back_channels = 1;
+ hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+ hInfo->channel_position[1] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT;
+ hInfo->channel_position[3] = BACK_CHANNEL_CENTER;
+ break;
+ case 5:
+ hInfo->num_front_channels = 3;
+ hInfo->num_back_channels = 2;
+ hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+ hInfo->channel_position[1] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT;
+ hInfo->channel_position[3] = BACK_CHANNEL_LEFT;
+ hInfo->channel_position[4] = BACK_CHANNEL_RIGHT;
+ break;
+ case 6:
+ hInfo->num_front_channels = 3;
+ hInfo->num_back_channels = 2;
+ hInfo->num_lfe_channels = 1;
+ hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+ hInfo->channel_position[1] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT;
+ hInfo->channel_position[3] = BACK_CHANNEL_LEFT;
+ hInfo->channel_position[4] = BACK_CHANNEL_RIGHT;
+ hInfo->channel_position[5] = LFE_CHANNEL;
+ break;
+ case 7:
+ hInfo->num_front_channels = 3;
+ hInfo->num_side_channels = 2;
+ hInfo->num_back_channels = 2;
+ hInfo->num_lfe_channels = 1;
+ hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+ hInfo->channel_position[1] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT;
+ hInfo->channel_position[3] = SIDE_CHANNEL_LEFT;
+ hInfo->channel_position[4] = SIDE_CHANNEL_RIGHT;
+ hInfo->channel_position[5] = BACK_CHANNEL_LEFT;
+ hInfo->channel_position[6] = BACK_CHANNEL_RIGHT;
+ hInfo->channel_position[7] = LFE_CHANNEL;
+ break;
+ default: /* channelConfiguration == 0 || channelConfiguration > 7 */
+ break;
+ }
+ }
+}
+
void* FAADAPI faacDecDecode(faacDecHandle hDecoder,
faacDecFrameInfo *hInfo,
uint8_t *buffer, uint32_t buffer_size)
@@ -406,8 +530,8 @@
#ifdef LTP_DEC
uint16_t *ltp_lag = hDecoder->ltp_lag;
#endif
- program_config *pce = &(hDecoder->pce);
+ program_config pce;
element *syntax_elements[MAX_SYNTAX_ELEMENTS];
element **elements;
int16_t *spec_data[MAX_CHANNELS];
@@ -450,7 +574,7 @@
/* decode the complete bitstream */
elements = raw_data_block(hDecoder, hInfo, ld, syntax_elements,
- spec_data, spec_coef, pce, drc);
+ spec_data, spec_coef, &pce, drc);
ch_ele = hDecoder->fr_ch_ele;
channels = hDecoder->fr_channels;
@@ -470,6 +594,20 @@
if (ld) free(ld);
ld = NULL;
+ if (!hDecoder->adts_header_present && !hDecoder->adif_header_present)
+ {
+ if (channels != hDecoder->channelConfiguration)
+ hDecoder->channelConfiguration = channels;
+
+ if (channels == 8) /* 7.1 */
+ hDecoder->channelConfiguration = 7;
+ if (channels == 7) /* not a standard channelConfiguration */
+ hDecoder->channelConfiguration = 0;
+ }
+
+ /* Make a channel configuration based on either a PCE or a channelConfiguration */
+ create_channel_config(hDecoder, hInfo);
+
/* number of samples in this frame */
hInfo->samples = frame_len*channels;
/* number of channels in this frame */
@@ -683,8 +821,8 @@
#endif
}
- sample_buffer = output_to_PCM(time_out, sample_buffer, channels,
- frame_len, outputFormat);
+ sample_buffer = output_to_PCM(hDecoder, time_out, sample_buffer,
+ channels, frame_len, outputFormat);
hDecoder->frame++;
#ifdef LD_DEC
--- a/libfaad/decoder.h
+++ b/libfaad/decoder.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: decoder.h,v 1.23 2003/07/07 21:11:18 menno Exp $
+** $Id: decoder.h,v 1.24 2003/07/08 13:45:45 menno Exp $
**/
#ifndef __DECODER_H__
@@ -65,7 +65,6 @@
#define ERROR_RESILIENCE_CAP (1<<4)
#define FIXED_POINT_CAP (1<<5)
-/* channel definitions */
#define FRONT_CHANNEL_CENTER (1)
#define FRONT_CHANNEL_LEFT (2)
#define FRONT_CHANNEL_RIGHT (3)
--- a/libfaad/output.c
+++ b/libfaad/output.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: output.c,v 1.17 2003/07/07 21:11:18 menno Exp $
+** $Id: output.c,v 1.18 2003/07/08 13:45:45 menno Exp $
**/
#include "common.h"
@@ -44,11 +44,13 @@
dither_t Dither;
double doubletmp;
-void* output_to_PCM(real_t **input, void *sample_buffer, uint8_t channels,
+void* output_to_PCM(faacDecHandle hDecoder,
+ real_t **input, void *sample_buffer, uint8_t channels,
uint16_t frame_len, uint8_t format)
{
uint8_t ch;
uint16_t i, j = 0;
+ uint8_t internal_channel;
int16_t *short_sample_buffer = (int16_t*)sample_buffer;
int32_t *int_sample_buffer = (int32_t*)sample_buffer;
@@ -58,6 +60,13 @@
/* Copy output to a standard PCM buffer */
for (ch = 0; ch < channels; ch++)
{
+ if (hDecoder->pce_set)
+ {
+ internal_channel = hDecoder->internal_channel[ch];
+ } else {
+ internal_channel = ch;
+ }
+
switch (format)
{
case FAAD_FMT_16BIT:
@@ -66,7 +75,7 @@
int32_t tmp;
real_t ftemp;
- ftemp = input[ch][i] + 0xff8000;
+ ftemp = input[internal_channel][i] + 0xff8000;
ftol(ftemp, short_sample_buffer[(i*channels)+ch]);
}
break;
@@ -73,7 +82,7 @@
case FAAD_FMT_16BIT_DITHER:
for(i = 0; i < frame_len; i++, j++)
{
- double Sum = input[ch][i] * 65535.f;
+ double Sum = input[internal_channel][i] * 65535.f;
int64_t val;
if(j > 31)
j = 0;
@@ -90,7 +99,7 @@
case FAAD_FMT_16BIT_H_SHAPE:
for(i = 0; i < frame_len; i++, j++)
{
- double Sum = input[ch][i] * 65535.f;
+ double Sum = input[internal_channel][i] * 65535.f;
int64_t val;
if(j > 31)
j = 0;
@@ -105,33 +114,33 @@
case FAAD_FMT_24BIT:
for(i = 0; i < frame_len; i++)
{
- if (input[ch][i] > (1<<15)-1)
- input[ch][i] = (1<<15)-1;
- else if (input[ch][i] < -(1<<15))
- input[ch][i] = -(1<<15);
- int_sample_buffer[(i*channels)+ch] = ROUND(input[ch][i]*(1<<8));
+ if (input[internal_channel][i] > (1<<15)-1)
+ input[internal_channel][i] = (1<<15)-1;
+ else if (input[internal_channel][i] < -(1<<15))
+ input[internal_channel][i] = -(1<<15);
+ int_sample_buffer[(i*channels)+ch] = ROUND(input[internal_channel][i]*(1<<8));
}
break;
case FAAD_FMT_32BIT:
for(i = 0; i < frame_len; i++)
{
- if (input[ch][i] > (1<<15)-1)
- input[ch][i] = (1<<15)-1;
- else if (input[ch][i] < -(1<<15))
- input[ch][i] = -(1<<15);
- int_sample_buffer[(i*channels)+ch] = ROUND32(input[ch][i]*(1<<16));
+ if (input[internal_channel][i] > (1<<15)-1)
+ input[internal_channel][i] = (1<<15)-1;
+ else if (input[internal_channel][i] < -(1<<15))
+ input[internal_channel][i] = -(1<<15);
+ int_sample_buffer[(i*channels)+ch] = ROUND32(input[internal_channel][i]*(1<<16));
}
break;
case FAAD_FMT_FLOAT:
for(i = 0; i < frame_len; i++)
{
- float_sample_buffer[(i*channels)+ch] = input[ch][i]*FLOAT_SCALE;
+ float_sample_buffer[(i*channels)+ch] = input[internal_channel][i]*FLOAT_SCALE;
}
break;
case FAAD_FMT_DOUBLE:
for(i = 0; i < frame_len; i++)
{
- double_sample_buffer[(i*channels)+ch] = (double)input[ch][i]*FLOAT_SCALE;
+ double_sample_buffer[(i*channels)+ch] = (double)input[internal_channel][i]*FLOAT_SCALE;
}
break;
}
@@ -170,7 +179,8 @@
#else
-void* output_to_PCM(real_t **input, void *sample_buffer, uint8_t channels,
+void* output_to_PCM(faacDecHandle hDecoder,
+ real_t **input, void *sample_buffer, uint8_t channels,
uint16_t frame_len, uint8_t format)
{
uint8_t ch;
--- a/libfaad/output.h
+++ b/libfaad/output.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: output.h,v 1.6 2002/08/26 19:08:39 menno Exp $
+** $Id: output.h,v 1.7 2003/07/08 13:45:45 menno Exp $
**/
#ifndef __OUTPUT_H__
@@ -26,7 +26,8 @@
extern "C" {
#endif
-void* output_to_PCM(real_t **input,
+void* output_to_PCM(faacDecHandle hDecoder,
+ real_t **input,
void *samplebuffer,
uint8_t channels,
uint16_t frame_len,
--- a/libfaad/structs.h
+++ b/libfaad/structs.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: structs.h,v 1.6 2003/07/07 21:11:18 menno Exp $
+** $Id: structs.h,v 1.7 2003/07/08 13:45:45 menno Exp $
**/
#ifndef __STRUCTS_H__
@@ -121,6 +121,14 @@
uint8_t comment_field_bytes;
uint8_t comment_field_data[257];
+
+ /* extra added values */
+ uint8_t num_front_channels;
+ uint8_t num_side_channels;
+ uint8_t num_back_channels;
+ uint8_t num_lfe_channels;
+ uint8_t sce_channel[16];
+ uint8_t cpe_channel[16];
} program_config;
typedef struct
@@ -317,7 +325,11 @@
uint32_t samplerate;
/* multichannel configuration */
- uint8_t channel_config[64];
+ uint8_t num_front_channels;
+ uint8_t num_side_channels;
+ uint8_t num_back_channels;
+ uint8_t num_lfe_channels;
+ uint8_t channel_position[MAX_CHANNELS];
} faacDecFrameInfo;
typedef struct
@@ -373,6 +385,7 @@
uint8_t pce_set;
program_config pce;
uint8_t channel_element[MAX_CHANNELS];
+ uint8_t internal_channel[MAX_CHANNELS];
/* Configuration data */
faacDecConfiguration config;
--- a/libfaad/syntax.c
+++ b/libfaad/syntax.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: syntax.c,v 1.46 2003/07/07 21:11:18 menno Exp $
+** $Id: syntax.c,v 1.47 2003/07/08 13:45:45 menno Exp $
**/
/*
@@ -65,10 +65,8 @@
program_config_element(&pce, ld);
mp4ASC->channelsConfiguration = pce.channels;
- /*
if (pce.num_valid_cc_elements)
return -3;
- */
}
#ifdef ERROR_RESILIENCE
@@ -103,6 +101,8 @@
{
uint8_t i;
+ memset(pce, 0, sizeof(program_config));
+
pce->channels = 0;
pce->element_instance_tag = (uint8_t)faad_getbits(ld, 4
@@ -153,72 +153,80 @@
for (i = 0; i < pce->num_front_channel_elements; i++)
{
- if ((pce->front_element_is_cpe[i] = faad_get1bit(ld
- DEBUGVAR(1,26,"program_config_element(): front_element_is_cpe"))) & 1)
+ pce->front_element_is_cpe[i] = faad_get1bit(ld
+ DEBUGVAR(1,26,"program_config_element(): front_element_is_cpe"));
+ pce->front_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,27,"program_config_element(): front_element_tag_select"));
+
+ if (pce->front_element_is_cpe[i] & 1)
{
-// printf("CPE ");
+ pce->cpe_channel[pce->front_element_tag_select[i]] = pce->channels;
+ pce->num_front_channels += 2;
pce->channels += 2;
} else {
-// printf("SCE ");
+ pce->sce_channel[pce->front_element_tag_select[i]] = pce->channels;
+ pce->num_front_channels++;
pce->channels++;
}
- pce->front_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
- DEBUGVAR(1,27,"program_config_element(): front_element_tag_select"));
-
-// printf("FRONT %d: %d\n", i, pce->front_element_tag_select[i]);
}
for (i = 0; i < pce->num_side_channel_elements; i++)
{
- if ((pce->side_element_is_cpe[i] = faad_get1bit(ld
- DEBUGVAR(1,28,"program_config_element(): side_element_is_cpe"))) & 1)
+ pce->side_element_is_cpe[i] = faad_get1bit(ld
+ DEBUGVAR(1,28,"program_config_element(): side_element_is_cpe"));
+ pce->side_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,29,"program_config_element(): side_element_tag_select"));
+
+ if (pce->side_element_is_cpe[i] & 1)
{
-// printf("CPE ");
+ pce->cpe_channel[pce->side_element_tag_select[i]] = pce->channels;
+ pce->num_side_channels += 2;
pce->channels += 2;
} else {
-// printf("SCE ");
+ pce->sce_channel[pce->side_element_tag_select[i]] = pce->channels;
+ pce->num_side_channels++;
pce->channels++;
}
- pce->side_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
- DEBUGVAR(1,29,"program_config_element(): side_element_tag_select"));
-
-// printf("SIDE %d: %d\n", i, pce->side_element_tag_select[i]);
}
for (i = 0; i < pce->num_back_channel_elements; i++)
{
- if ((pce->back_element_is_cpe[i] = faad_get1bit(ld
- DEBUGVAR(1,30,"program_config_element(): back_element_is_cpe"))) & 1)
+ pce->back_element_is_cpe[i] = faad_get1bit(ld
+ DEBUGVAR(1,30,"program_config_element(): back_element_is_cpe"));
+ pce->back_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,31,"program_config_element(): back_element_tag_select"));
+
+ if (pce->back_element_is_cpe[i] & 1)
{
-// printf("CPE ");
+ pce->cpe_channel[pce->back_element_tag_select[i]] = pce->channels;
pce->channels += 2;
+ pce->num_back_channels += 2;
} else {
-// printf("SCE ");
+ pce->sce_channel[pce->back_element_tag_select[i]] = pce->channels;
+ pce->num_back_channels++;
pce->channels++;
}
- pce->back_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
- DEBUGVAR(1,31,"program_config_element(): back_element_tag_select"));
-
-// printf("BACK %d: %d\n", i, pce->back_element_tag_select[i]);
}
for (i = 0; i < pce->num_lfe_channel_elements; i++)
{
- pce->channels++;
pce->lfe_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
DEBUGVAR(1,32,"program_config_element(): lfe_element_tag_select"));
-// printf("LFE %d: %d\n", i, pce->lfe_element_tag_select[i]);
+ pce->sce_channel[pce->lfe_element_tag_select[i]] = pce->channels;
+ pce->num_lfe_channels++;
+ pce->channels++;
}
for (i = 0; i < pce->num_assoc_data_elements; i++)
- {
pce->assoc_data_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
- DEBUGVAR(1,33,"program_config_element(): assoc_data_element_tag_select"));
- }
+ DEBUGVAR(1,33,"program_config_element(): assoc_data_element_tag_select"));
for (i = 0; i < pce->num_valid_cc_elements; i++)
{
+ /* have to count these as channels too?? (1 or 2) */
+ pce->channels += 2;
+
pce->cc_element_is_ind_sw[i] = faad_get1bit(ld
DEBUGVAR(1,34,"program_config_element(): cc_element_is_ind_sw"));
pce->valid_cc_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
@@ -271,6 +279,9 @@
hInfo->error = single_lfe_channel_element(hDecoder, ele,
ld, spec_data[channels]);
+ if (hDecoder->pce_set)
+ hDecoder->internal_channel[hDecoder->pce.sce_channel[ele->element_instance_tag]] = channels;
+
if (id_syn_ele == ID_SCE)
hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
else /* LFE */
@@ -315,6 +326,12 @@
hInfo->error = channel_pair_element(hDecoder, ele,
ld, spec_data[channels], spec_data[channels+1]);
+ if (hDecoder->pce_set)
+ {
+ hDecoder->internal_channel[hDecoder->pce.cpe_channel[ele->element_instance_tag]] = channels;
+ hDecoder->internal_channel[hDecoder->pce.cpe_channel[ele->element_instance_tag]+1] = channels+1;
+ }
+
hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
hDecoder->channel_element[channels+1] = hDecoder->fr_ch_ele;
@@ -816,7 +833,7 @@
memset(&el_empty, 0, sizeof(element));
memset(&ics_empty, 0, sizeof(ic_stream));
- faad_getbits(ld, LEN_TAG
+ c = faad_getbits(ld, LEN_TAG
DEBUGVAR(1,900,"coupling_channel_element(): element_instance_tag"));
ind_sw_cce_flag = faad_get1bit(ld