From cc2160de5cc05dc3aa77f3a34358e66f6193c8c9 Mon Sep 17 00:00:00 2001 From: Michał Cichoń Date: Tue, 26 Jun 2012 20:35:30 +0200 Subject: Add support for AAC. --- faad2/src/aacDECdrop/Script.rc | 214 +++++++ faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.sln | 33 ++ faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.vcproj | 335 +++++++++++ faad2/src/aacDECdrop/audio.c | 494 ++++++++++++++++ faad2/src/aacDECdrop/audio.h | 71 +++ faad2/src/aacDECdrop/decode.c | 566 ++++++++++++++++++ faad2/src/aacDECdrop/decode.h | 55 ++ faad2/src/aacDECdrop/decthread.c | 194 +++++++ faad2/src/aacDECdrop/decthread.h | 19 + faad2/src/aacDECdrop/main.c | 678 ++++++++++++++++++++++ faad2/src/aacDECdrop/misc.c | 124 ++++ faad2/src/aacDECdrop/misc.h | 25 + faad2/src/aacDECdrop/resource.h | 54 ++ faad2/src/aacDECdrop/resource/AAC01.bmp | Bin 0 -> 2134 bytes faad2/src/aacDECdrop/resource/AAC01.ico | Bin 0 -> 2238 bytes faad2/src/aacDECdrop/resource/AAC02.bmp | Bin 0 -> 2134 bytes faad2/src/aacDECdrop/resource/AAC03.bmp | Bin 0 -> 2134 bytes faad2/src/aacDECdrop/resource/AAC04.bmp | Bin 0 -> 2134 bytes faad2/src/aacDECdrop/resource/AAC05.bmp | Bin 0 -> 2134 bytes faad2/src/aacDECdrop/resource/AAC06.bmp | Bin 0 -> 2134 bytes faad2/src/aacDECdrop/resource/AAC07.bmp | Bin 0 -> 2134 bytes faad2/src/aacDECdrop/resource/AAC08.bmp | Bin 0 -> 2134 bytes faad2/src/aacDECdrop/wave_out.c | 190 ++++++ faad2/src/aacDECdrop/wave_out.h | 50 ++ 24 files changed, 3102 insertions(+) create mode 100644 faad2/src/aacDECdrop/Script.rc create mode 100644 faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.sln create mode 100644 faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.vcproj create mode 100644 faad2/src/aacDECdrop/audio.c create mode 100644 faad2/src/aacDECdrop/audio.h create mode 100644 faad2/src/aacDECdrop/decode.c create mode 100644 faad2/src/aacDECdrop/decode.h create mode 100644 faad2/src/aacDECdrop/decthread.c create mode 100644 faad2/src/aacDECdrop/decthread.h create mode 100644 faad2/src/aacDECdrop/main.c create mode 100644 faad2/src/aacDECdrop/misc.c create mode 100644 faad2/src/aacDECdrop/misc.h create mode 100644 faad2/src/aacDECdrop/resource.h create mode 100644 faad2/src/aacDECdrop/resource/AAC01.bmp create mode 100644 faad2/src/aacDECdrop/resource/AAC01.ico create mode 100644 faad2/src/aacDECdrop/resource/AAC02.bmp create mode 100644 faad2/src/aacDECdrop/resource/AAC03.bmp create mode 100644 faad2/src/aacDECdrop/resource/AAC04.bmp create mode 100644 faad2/src/aacDECdrop/resource/AAC05.bmp create mode 100644 faad2/src/aacDECdrop/resource/AAC06.bmp create mode 100644 faad2/src/aacDECdrop/resource/AAC07.bmp create mode 100644 faad2/src/aacDECdrop/resource/AAC08.bmp create mode 100644 faad2/src/aacDECdrop/wave_out.c create mode 100644 faad2/src/aacDECdrop/wave_out.h (limited to 'faad2/src/aacDECdrop') diff --git a/faad2/src/aacDECdrop/Script.rc b/faad2/src/aacDECdrop/Script.rc new file mode 100644 index 0000000..d771f73 --- /dev/null +++ b/faad2/src/aacDECdrop/Script.rc @@ -0,0 +1,214 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_TF01 BITMAP "resource/AAC01.bmp" +IDB_TF02 BITMAP "resource/AAC02.bmp" +IDB_TF03 BITMAP "resource/AAC03.bmp" +IDB_TF04 BITMAP "resource/AAC04.bmp" +IDB_TF05 BITMAP "resource/AAC05.bmp" +IDB_TF06 BITMAP "resource/AAC06.bmp" +IDB_TF07 BITMAP "resource/AAC07.bmp" +IDB_TF08 BITMAP "resource/AAC08.bmp" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU +BEGIN + POPUP "Menu" + BEGIN + MENUITEM "&Decoder Options", IDM_VOLUME + MENUITEM "&Stop Decoding", IDM_STOP_DEC + MENUITEM "&About", IDM_ABOUT + MENUITEM SEPARATOR + MENUITEM "&Errors to Log File", IDM_LOGERR + MENUITEM "&Always on Top", IDM_ONTOP + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", IDM_QUIT + END + MENUITEM SEPARATOR +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "resource/AAC01.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_VOLUME DIALOGEX 0, 0, 255, 257 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Decoder Options V1.2" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + GROUPBOX "Decoding Settings",IDC_STATIC,7,7,241,23 + CONTROL "Playback",IDC_PLAYBACK,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,15,17,55,10 + CONTROL "Decode to File",IDC_DECODE,"Button",BS_AUTORADIOBUTTON, + 125,17,65,10 + GROUPBOX "Output Format Settings",IDC_STATIC,7,31,241,50 + CONTROL "Microsoft WAV",IDC_WAV,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,15,45,65,10 + CONTROL "Apple/SGI AIFF",IDC_AIFF,"Button",BS_AUTORADIOBUTTON | + WS_DISABLED,125,45,65,10 + CONTROL "Sun/NeXT AU",IDC_SUNAU,"Button",BS_AUTORADIOBUTTON | + WS_DISABLED,15,60,65,10 + CONTROL "DEC AU",IDC_DECAU,"Button",BS_AUTORADIOBUTTON | + WS_DISABLED,125,60,65,10 + GROUPBOX "Output Sample Format Settings",IDC_STATIC,7,82,241,91 + CONTROL "16 bit PCM",IDC_16BIT,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,15,96,65,10 + CONTROL "24 bit PCM",IDC_24BIT,"Button",BS_AUTORADIOBUTTON,125, + 96,65,10 + CONTROL "32 bit PCM",IDC_32BIT,"Button",BS_AUTORADIOBUTTON,15, + 111,65,10 + CONTROL "32 bit floats",IDC_FLOATS,"Button",BS_AUTORADIOBUTTON, + 125,111,65,10 + CONTROL "16 bit PCM - Dithered",IDC_16BIT_DITHER,"Button", + BS_AUTORADIOBUTTON,15,126,83,10 + CONTROL "16 bit PCM - Dithered with",IDC_16BIT_L_SHAPE,"Button", + BS_AUTORADIOBUTTON,125,126,98,10 + CONTROL "16 bit PCM - Dithered with",IDC_16BIT_M_SHAPE,"Button", + BS_AUTORADIOBUTTON,15,146,98,10 + CONTROL "16 bit PCM - Dithered with",IDC_16BIT_H_SHAPE,"Button", + BS_AUTORADIOBUTTON,125,146,98,10 + LTEXT "LIGHT Noise Shaping",IDC_STATIC,138,136,70,8 + LTEXT "HEAVY Noise Shaping",IDC_STATIC,138,156,73,8 + LTEXT "MEDIUM Noise Shaping",IDC_STATIC,28,156,78,8 + GROUPBOX "Object Type Settings",IDC_STATIC,7,174,241,50 + CONTROL "Main",IDC_MAIN,"Button",BS_AUTORADIOBUTTON | WS_GROUP, + 15,188,65,10 + CONTROL "Low Complexity",IDC_LC,"Button",BS_AUTORADIOBUTTON,125, + 188,65,10 + CONTROL "Long Term Prediction",IDC_LTP,"Button", + BS_AUTORADIOBUTTON,15,203,85,10 + CONTROL "Low Delay",IDC_LD,"Button",BS_AUTORADIOBUTTON,125,203, + 65,10 + DEFPUSHBUTTON "Accept",IDC_BUTTON1,102,233,50,16 +END + +IDD_ABOUT DIALOGEX 0, 0, 255, 194 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "About aacDECdrop V1.22" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + GROUPBOX "",IDC_STATIC,7,5,241,157 + CTEXT "A decoder to decode/playback aac/Mpeg4 files.", + IDC_STATIC,70,13,155,8 + CTEXT "Copyright 2002 John Edwards.",IDC_STATIC,70,30,97,8 + CTEXT "Utilises standard libfaad2 from Menno Bakker.", + IDC_STATIC,70,46,145,8 + LTEXT "This program is free software; you can redistribute it and/or modify it", + IDC_STATIC,13,62,212,8 + LTEXT "under the terms of the GNU Public Licence as published by the Free", + IDC_STATIC,13,72,215,8 + LTEXT "Software Foundation; either version 2 of the Licence, or (at your option)", + IDC_STATIC,13,82,224,8 + LTEXT "any later version.",IDC_STATIC,13,92,54,8 + LTEXT "This program is distributed in the hope that it will be useful, but", + IDC_STATIC,13,112,195,8 + LTEXT "WITHOUT ANY WARRANTY; without even the implied warranty of", + IDC_STATIC,13,122,213,8 + LTEXT "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.", + IDC_STATIC,13,132,218,8 + LTEXT "See the GNU General Public Licence for more details.", + IDC_STATIC,13,142,170,8 + DEFPUSHBUTTON "OK",IDC_BUTTON6,102,171,50,16 + CONTROL 112,IDC_STATIC,"Static",SS_BITMAP | SS_SUNKEN,12,13,43, + 40 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_VOLUME, DIALOG + BEGIN + BOTTOMMARGIN, 256 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.sln b/faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.sln new file mode 100644 index 0000000..47a5572 --- /dev/null +++ b/faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.sln @@ -0,0 +1,33 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aacDECdrop", "aacDECdrop.vcproj", "{C23A88D7-4997-4026-BBDB-5B0B2B22FDFF}" + ProjectSection(ProjectDependencies) = postProject + {F470BB4A-7675-4D6A-B310-41F33AC6F987} = {F470BB4A-7675-4D6A-B310-41F33AC6F987} + {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114} = {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "..\..\libfaad\libfaad.vcproj", "{BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4ff", "..\..\common\mp4ff\mp4ff.vcproj", "{F470BB4A-7675-4D6A-B310-41F33AC6F987}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C23A88D7-4997-4026-BBDB-5B0B2B22FDFF}.Debug|Win32.ActiveCfg = Debug|Win32 + {C23A88D7-4997-4026-BBDB-5B0B2B22FDFF}.Debug|Win32.Build.0 = Debug|Win32 + {C23A88D7-4997-4026-BBDB-5B0B2B22FDFF}.Release|Win32.ActiveCfg = Release|Win32 + {C23A88D7-4997-4026-BBDB-5B0B2B22FDFF}.Release|Win32.Build.0 = Release|Win32 + {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}.Debug|Win32.ActiveCfg = Debug|Win32 + {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}.Release|Win32.ActiveCfg = Release|Win32 + {F470BB4A-7675-4D6A-B310-41F33AC6F987}.Debug|Win32.ActiveCfg = Debug|Win32 + {F470BB4A-7675-4D6A-B310-41F33AC6F987}.Debug|Win32.Build.0 = Debug|Win32 + {F470BB4A-7675-4D6A-B310-41F33AC6F987}.Release|Win32.ActiveCfg = Release|Win32 + {F470BB4A-7675-4D6A-B310-41F33AC6F987}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.vcproj b/faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.vcproj new file mode 100644 index 0000000..6487e15 --- /dev/null +++ b/faad2/src/aacDECdrop/aacDECdrop/aacDECdrop.vcproj @@ -0,0 +1,335 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/faad2/src/aacDECdrop/audio.c b/faad2/src/aacDECdrop/audio.c new file mode 100644 index 0000000..843d650 --- /dev/null +++ b/faad2/src/aacDECdrop/audio.c @@ -0,0 +1,494 @@ +/* +** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding +** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com +** +** 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. +** +** Any non-GPL usage of this software or parts of this software is strictly +** forbidden. +** +** Commercial non-GPL licensing of this software is possible. +** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. +** +** $Id: audio.c,v 1.11 2004/02/06 10:23:27 menno Exp $ +**/ + +#ifdef _WIN32 +#include +#endif +#include +#include +#include +#include +#include +#include "audio.h" + + +audio_file *open_audio_file(char *infile, int samplerate, int channels, + int outputFormat, int fileType, long channelMask) +{ + audio_file *aufile = malloc(sizeof(audio_file)); + + aufile->outputFormat = outputFormat; + + aufile->samplerate = samplerate; + aufile->channels = channels; + aufile->total_samples = 0; + aufile->fileType = fileType; + aufile->channelMask = channelMask; + + switch (outputFormat) + { + case FAAD_FMT_16BIT: + aufile->bits_per_sample = 16; + break; + case FAAD_FMT_24BIT: + aufile->bits_per_sample = 24; + break; + case FAAD_FMT_32BIT: + case FAAD_FMT_FLOAT: + aufile->bits_per_sample = 32; + break; + default: + if (aufile) free(aufile); + return NULL; + } + + if(infile[0] == '-') + { +#ifdef _WIN32 + setmode(fileno(stdout), O_BINARY); +#endif + aufile->sndfile = stdout; + } else { + aufile->sndfile = fopen(infile, "wb"); + } + + if (aufile->sndfile == NULL) + { + if (aufile) free(aufile); + return NULL; + } + + if (aufile->fileType == OUTPUT_WAV) + { + if (aufile->channelMask) + write_wav_extensible_header(aufile, aufile->channelMask); + else + write_wav_header(aufile); + } + + return aufile; +} + +int write_audio_file(audio_file *aufile, void *sample_buffer, int samples, int offset) +{ + char *buf = (char *)sample_buffer; + switch (aufile->outputFormat) + { + case FAAD_FMT_16BIT: + return write_audio_16bit(aufile, buf + offset*2, samples); + case FAAD_FMT_24BIT: + return write_audio_24bit(aufile, buf + offset*4, samples); + case FAAD_FMT_32BIT: + return write_audio_32bit(aufile, buf + offset*4, samples); + case FAAD_FMT_FLOAT: + return write_audio_float(aufile, buf + offset*4, samples); + default: + return 0; + } + + return 0; +} + +void close_audio_file(audio_file *aufile) +{ + if (aufile->fileType == OUTPUT_WAV) + { + fseek(aufile->sndfile, 0, SEEK_SET); + + if (aufile->channelMask) + write_wav_extensible_header(aufile, aufile->channelMask); + else + write_wav_header(aufile); + } + + fclose(aufile->sndfile); + + if (aufile) free(aufile); +} + +static int write_wav_header(audio_file *aufile) +{ + unsigned char header[44]; + unsigned char* p = header; + unsigned int bytes = (aufile->bits_per_sample + 7) / 8; + float data_size = (float)bytes * aufile->total_samples; + unsigned long word32; + + *p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F'; + + word32 = (data_size + (44 - 8) < (float)MAXWAVESIZE) ? + (unsigned long)data_size + (44 - 8) : (unsigned long)MAXWAVESIZE; + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + *p++ = (unsigned char)(word32 >> 16); + *p++ = (unsigned char)(word32 >> 24); + + *p++ = 'W'; *p++ = 'A'; *p++ = 'V'; *p++ = 'E'; + + *p++ = 'f'; *p++ = 'm'; *p++ = 't'; *p++ = ' '; + + *p++ = 0x10; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; + + if (aufile->outputFormat == FAAD_FMT_FLOAT) + { + *p++ = 0x03; *p++ = 0x00; + } else { + *p++ = 0x01; *p++ = 0x00; + } + + *p++ = (unsigned char)(aufile->channels >> 0); + *p++ = (unsigned char)(aufile->channels >> 8); + + word32 = (unsigned long)(aufile->samplerate + 0.5); + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + *p++ = (unsigned char)(word32 >> 16); + *p++ = (unsigned char)(word32 >> 24); + + word32 = aufile->samplerate * bytes * aufile->channels; + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + *p++ = (unsigned char)(word32 >> 16); + *p++ = (unsigned char)(word32 >> 24); + + word32 = bytes * aufile->channels; + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + + *p++ = (unsigned char)(aufile->bits_per_sample >> 0); + *p++ = (unsigned char)(aufile->bits_per_sample >> 8); + + *p++ = 'd'; *p++ = 'a'; *p++ = 't'; *p++ = 'a'; + + word32 = data_size < MAXWAVESIZE ? + (unsigned long)data_size : (unsigned long)MAXWAVESIZE; + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + *p++ = (unsigned char)(word32 >> 16); + *p++ = (unsigned char)(word32 >> 24); + + return fwrite(header, sizeof(header), 1, aufile->sndfile); +} + +static int write_wav_extensible_header(audio_file *aufile, long channelMask) +{ + 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; + unsigned long word32; + + *p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F'; + + 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); + *p++ = (unsigned char)(word32 >> 24); + + *p++ = 'W'; *p++ = 'A'; *p++ = 'V'; *p++ = 'E'; + + *p++ = 'f'; *p++ = 'm'; *p++ = 't'; *p++ = ' '; + + *p++ = /*0x10*/0x28; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; + + /* WAVE_FORMAT_EXTENSIBLE */ + *p++ = 0xFE; *p++ = 0xFF; + + *p++ = (unsigned char)(aufile->channels >> 0); + *p++ = (unsigned char)(aufile->channels >> 8); + + word32 = (unsigned long)(aufile->samplerate + 0.5); + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + *p++ = (unsigned char)(word32 >> 16); + *p++ = (unsigned char)(word32 >> 24); + + word32 = aufile->samplerate * bytes * aufile->channels; + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + *p++ = (unsigned char)(word32 >> 16); + *p++ = (unsigned char)(word32 >> 24); + + word32 = bytes * aufile->channels; + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + + *p++ = (unsigned char)(aufile->bits_per_sample >> 0); + *p++ = (unsigned char)(aufile->bits_per_sample >> 8); + + /* cbSize */ + *p++ = (unsigned char)(22); + *p++ = (unsigned char)(0); + + /* WAVEFORMATEXTENSIBLE */ + + /* wValidBitsPerSample */ + *p++ = (unsigned char)(aufile->bits_per_sample >> 0); + *p++ = (unsigned char)(aufile->bits_per_sample >> 8); + + /* dwChannelMask */ + word32 = channelMask; + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + *p++ = (unsigned char)(word32 >> 16); + *p++ = (unsigned char)(word32 >> 24); + + /* SubFormat */ + if (aufile->outputFormat == FAAD_FMT_FLOAT) + { + /* KSDATAFORMAT_SUBTYPE_IEEE_FLOAT: 00000003-0000-0010-8000-00aa00389b71 */ + *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++ = 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; + } + + /* end WAVEFORMATEXTENSIBLE */ + + *p++ = 'd'; *p++ = 'a'; *p++ = 't'; *p++ = 'a'; + + word32 = data_size < MAXWAVESIZE ? + (unsigned long)data_size : (unsigned long)MAXWAVESIZE; + *p++ = (unsigned char)(word32 >> 0); + *p++ = (unsigned char)(word32 >> 8); + *p++ = (unsigned char)(word32 >> 16); + *p++ = (unsigned char)(word32 >> 24); + + return fwrite(header, sizeof(header), 1, aufile->sndfile); +} + +static int write_audio_16bit(audio_file *aufile, void *sample_buffer, + unsigned int samples) +{ + int ret; + unsigned int i; + short *sample_buffer16 = (short*)sample_buffer; + 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) + { + 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); + data[i*2+1] = (char)((sample_buffer16[i] >> 8) & 0xFF); + } + + ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile); + + if (data) free(data); + + return ret; +} + +static int write_audio_24bit(audio_file *aufile, void *sample_buffer, + unsigned int samples) +{ + int ret; + unsigned int i; + long *sample_buffer24 = (long*)sample_buffer; + 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) + { + 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); + data[i*3+1] = (char)((sample_buffer24[i] >> 8) & 0xFF); + data[i*3+2] = (char)((sample_buffer24[i] >> 16) & 0xFF); + } + + ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile); + + if (data) free(data); + + return ret; +} + +static int write_audio_32bit(audio_file *aufile, void *sample_buffer, + unsigned int samples) +{ + int ret; + unsigned int i; + long *sample_buffer32 = (long*)sample_buffer; + 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) + { + 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); + data[i*4+1] = (char)((sample_buffer32[i] >> 8) & 0xFF); + data[i*4+2] = (char)((sample_buffer32[i] >> 16) & 0xFF); + data[i*4+3] = (char)((sample_buffer32[i] >> 24) & 0xFF); + } + + ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile); + + if (data) free(data); + + return ret; +} + +static int write_audio_float(audio_file *aufile, void *sample_buffer, + unsigned int samples) +{ + int ret; + unsigned int i; + float *sample_buffer_f = (float*)sample_buffer; + 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++) + { + int exponent, mantissa, negative = 0 ; + float in = sample_buffer_f[i]; + + data[i*4] = 0; data[i*4+1] = 0; data[i*4+2] = 0; data[i*4+3] = 0; + if (in == 0.0) + continue; + + if (in < 0.0) + { + in *= -1.0; + negative = 1; + } + in = (float)frexp(in, &exponent); + exponent += 126; + in *= (float)0x1000000; + mantissa = (((int)in) & 0x7FFFFF); + + if (negative) + data[i*4+3] |= 0x80; + + if (exponent & 0x01) + data[i*4+2] |= 0x80; + + data[i*4] = mantissa & 0xFF; + data[i*4+1] = (mantissa >> 8) & 0xFF; + data[i*4+2] |= (mantissa >> 16) & 0x7F; + data[i*4+3] |= (exponent >> 1) & 0x7F; + } + + ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile); + + if (data) free(data); + + return ret; +} diff --git a/faad2/src/aacDECdrop/audio.h b/faad2/src/aacDECdrop/audio.h new file mode 100644 index 0000000..941c6ec --- /dev/null +++ b/faad2/src/aacDECdrop/audio.h @@ -0,0 +1,71 @@ +/* +** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding +** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com +** +** 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. +** +** Any non-GPL usage of this software or parts of this software is strictly +** forbidden. +** +** Commercial non-GPL licensing of this software is possible. +** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. +** +** $Id: audio.h,v 1.9 2004/02/06 10:23:27 menno Exp $ +**/ + +#ifndef AUDIO_H_INCLUDED +#define AUDIO_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAXWAVESIZE 4294967040LU + +#define OUTPUT_WAV 1 +#define OUTPUT_RAW 2 + +typedef struct +{ + int outputFormat; + FILE *sndfile; + unsigned int fileType; + unsigned long samplerate; + 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, long channelMask); +int write_audio_file(audio_file *aufile, void *sample_buffer, int samples, int offset); +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, + unsigned int samples); +static int write_audio_32bit(audio_file *aufile, void *sample_buffer, + unsigned int samples); +static int write_audio_float(audio_file *aufile, void *sample_buffer, + unsigned int samples); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/faad2/src/aacDECdrop/decode.c b/faad2/src/aacDECdrop/decode.c new file mode 100644 index 0000000..8eca01c --- /dev/null +++ b/faad2/src/aacDECdrop/decode.c @@ -0,0 +1,566 @@ +/* +** 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. +** +** $Id: decode.c,v 1.16 2004/04/03 19:08:37 menno Exp $ +** $Id: decode.c,v 1.16 2004/04/03 19:08:37 menno Exp $ +**/ + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#define off_t __int64 +#else +#include +#endif + +#include +#include + +#include +#include + +#include "audio.h" +#include "decode.h" +#include "misc.h" +#include "wave_out.h" + +#ifndef min +#define min(a,b) ( (a) < (b) ? (a) : (b) ) +#endif + +#define MAX_CHANNELS 8 /* make this higher to support files with + more channels */ + +/* FAAD file buffering routines */ +/* declare buffering variables */ +#define DEC_BUFF_VARS \ + int fileread, bytesconsumed, k; \ + int buffercount = 0, buffer_index = 0; \ + unsigned char *buffer; \ + unsigned int bytes_in_buffer = 0; + +/* initialise buffering */ +#define INIT_BUFF(file) \ + fseek(file, 0, SEEK_END); \ + fileread = ftell(file); \ + fseek(file, 0, SEEK_SET); \ + buffer = (unsigned char*)malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS); \ + memset(buffer, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS); \ + bytes_in_buffer = fread(buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, file); + +/* skip bytes in buffer */ +#define UPDATE_BUFF_SKIP(bytes) \ + fseek(infile, bytes, SEEK_SET); \ + buffer_index += bytes; \ + buffercount = 0; \ + bytes_in_buffer = fread(buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, infile); + +/* update buffer */ +#define UPDATE_BUFF_READ \ + if (bytesconsumed > 0) { \ + for (k = 0; k < (FAAD_MIN_STREAMSIZE*MAX_CHANNELS - bytesconsumed); k++) \ + buffer[k] = buffer[k + bytesconsumed]; \ + bytes_in_buffer += fread(buffer + (FAAD_MIN_STREAMSIZE*MAX_CHANNELS) - bytesconsumed, 1, bytesconsumed, infile); \ + bytesconsumed = 0; \ + } + +/* update buffer indices after NeAACDecDecode */ +#define UPDATE_BUFF_IDX(frame) \ + bytesconsumed += frame.bytesconsumed; \ + buffer_index += frame.bytesconsumed; \ + bytes_in_buffer -= frame.bytesconsumed; + +/* true if decoding has to stop because of EOF */ +#define IS_FILE_END buffer_index >= fileread + +/* end buffering */ +#define END_BUFF if (buffer) free(buffer); + + + +/* globals */ +char *progName; +extern int stop_decoding; + +int id3v2_tag(unsigned char *buffer) +{ + if (strncmp(buffer, "ID3", 3) == 0) { + unsigned long tagsize; + + /* high bit is not used */ + tagsize = (buffer[6] << 21) | (buffer[7] << 14) | + (buffer[8] << 7) | (buffer[9] << 0); + + tagsize += 10; + + return tagsize; + } else { + return 0; + } +} + +char *file_ext[] = +{ + NULL, + ".wav", + ".aif", + ".au", + ".au", + NULL +}; + +/* 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(NeAACDecFrameInfo *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; + } +} + +int decodeAACfile(char *sndfile, int def_srate, aac_dec_opt *opt) +{ + int tagsize; + unsigned long samplerate; + unsigned char channels; + void *sample_buffer; + + FILE *infile; + + audio_file *aufile; + + NeAACDecHandle hDecoder; + NeAACDecFrameInfo frameInfo; + NeAACDecConfigurationPtr config; + + int first_time = 1; + + + /* declare variables for buffering */ + DEC_BUFF_VARS + + infile = fopen(opt->filename, "rb"); + if (infile == NULL) + { + /* unable to open file */ + error_handler("Error opening file: %s\n", opt->filename); + return 1; + } + INIT_BUFF(infile) + + tagsize = id3v2_tag(buffer); + if (tagsize) + { + UPDATE_BUFF_SKIP(tagsize) + } + + hDecoder = NeAACDecOpen(); + + /* Set the default object type and samplerate */ + /* This is useful for RAW AAC files */ + config = NeAACDecGetCurrentConfiguration(hDecoder); + if (def_srate) + config->defSampleRate = def_srate; + config->defObjectType = opt->object_type; + config->outputFormat = opt->output_format; + + NeAACDecSetConfiguration(hDecoder, config); + + if ((bytesconsumed = NeAACDecInit(hDecoder, buffer, bytes_in_buffer, + &samplerate, &channels)) < 0) + { + /* If some error initializing occured, skip the file */ + error_handler("Error initializing decoder library.\n"); + END_BUFF + NeAACDecClose(hDecoder); + fclose(infile); + return 1; + } + buffer_index += bytesconsumed; + + do + { + /* update buffer */ + UPDATE_BUFF_READ + + sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer); + + /* update buffer indices */ + UPDATE_BUFF_IDX(frameInfo) + + if (frameInfo.error > 0) + { + error_handler("Error: %s\n", + NeAACDecGetErrorMessage(frameInfo.error)); + } + + opt->progress_update((long)fileread, buffer_index); + + /* open the sound file now that the number of channels are known */ + if (first_time && !frameInfo.error) + { + if(opt->decode_mode == 0) + { + if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE, + frameInfo.channels) < 0) + { + error_handler("\nCan't access %s\n", "WAVE OUT"); + END_BUFF + NeAACDecClose(hDecoder); + fclose(infile); + return (0); + } + } + else + { + aufile = open_audio_file(sndfile, samplerate, frameInfo.channels, + opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo)); + + if (aufile == NULL) + { + END_BUFF + NeAACDecClose(hDecoder); + fclose(infile); + return 0; + } + } + first_time = 0; + } + + if ((frameInfo.error == 0) && (frameInfo.samples > 0)) + { + if(opt->decode_mode == 0) + WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples); + else + write_audio_file(aufile, sample_buffer, frameInfo.samples, 0); + } + + if (buffer_index >= fileread) + sample_buffer = NULL; /* to make sure it stops now */ + + if(stop_decoding) + break; + + } while (sample_buffer != NULL); + + NeAACDecClose(hDecoder); + + fclose(infile); + + if(opt->decode_mode == 0) + WIN_Audio_close(); + else + { + if (!first_time) + close_audio_file(aufile); + } + + END_BUFF + + return frameInfo.error; +} + +int GetAACTrack(mp4ff_t *infile) +{ + /* find AAC track */ + int i, rc; + int numTracks = mp4ff_total_tracks(infile); + + for (i = 0; i < numTracks; i++) + { + unsigned char *buff = NULL; + int buff_size = 0; + mp4AudioSpecificConfig mp4ASC; + + mp4ff_get_decoder_config(infile, i, &buff, &buff_size); + + if (buff) + { + rc = NeAACDecAudioSpecificConfig(buff, buff_size, &mp4ASC); + free(buff); + + if (rc < 0) + continue; + return i; + } + } + + /* can't decode this */ + return -1; +} + +unsigned long srates[] = +{ + 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, + 12000, 11025, 8000 +}; + +uint32_t read_callback(void *user_data, void *buffer, uint32_t length) +{ + return fread(buffer, 1, length, (FILE*)user_data); +} + +uint32_t seek_callback(void *user_data, uint64_t position) +{ + return fseek((FILE*)user_data, position, SEEK_SET); +} + +int decodeMP4file(char *sndfile, aac_dec_opt *opt) +{ + int track; + unsigned long samplerate; + unsigned char channels; + void *sample_buffer; + + mp4ff_t *infile; + FILE *mp4File; + int sampleId, numSamples; + + audio_file *aufile; + + NeAACDecHandle hDecoder; + NeAACDecFrameInfo frameInfo; + + unsigned char *buffer; + int buffer_size; + + int first_time = 1; + + /* initialise the callback structure */ + mp4ff_callback_t *mp4cb = malloc(sizeof(mp4ff_callback_t)); + + mp4File = fopen(opt->filename, "rb"); + mp4cb->read = read_callback; + mp4cb->seek = seek_callback; + mp4cb->user_data = mp4File; + + infile = mp4ff_open_read(mp4cb); + if (!infile) + { + /* unable to open file */ + error_handler("Error opening file: %s\n", opt->filename); + return 1; + } + + if ((track = GetAACTrack(infile)) < 0) + { + error_handler("Unable to find correct AAC sound track in the MP4 file.\n"); + mp4ff_close(infile); + free(mp4cb); + fclose(mp4File); + return 1; + } + + buffer = NULL; + buffer_size = 0; + mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size); + + hDecoder = NeAACDecOpen(); + + if(NeAACDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0) + { + /* If some error initializing occured, skip the file */ + error_handler("Error initializing decoder library.\n"); + NeAACDecClose(hDecoder); + mp4ff_close(infile); + free(mp4cb); + fclose(mp4File); + return 1; + } + if (buffer) + free(buffer); + + numSamples = mp4ff_num_samples(infile, track); + + for (sampleId = 0; sampleId < numSamples; sampleId++) + { + int rc; + + /* get access unit from MP4 file */ + buffer = NULL; + buffer_size = 0; + + rc = mp4ff_read_sample(infile, track, sampleId, &buffer, &buffer_size); + if (rc == 0) + { + error_handler("Reading from MP4 file failed.\n"); + NeAACDecClose(hDecoder); + mp4ff_close(infile); + free(mp4cb); + fclose(mp4File); + return 1; + } + + sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, buffer_size); + + if (buffer) + free(buffer); + + opt->progress_update((long)numSamples, sampleId); + + /* open the sound file now that the number of channels are known */ + if (first_time && !frameInfo.error) + { + if(opt->decode_mode == 0) + { + if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE, + frameInfo.channels) < 0) + { + error_handler("\nCan't access %s\n", "WAVE OUT"); + NeAACDecClose(hDecoder); + mp4ff_close(infile); + free(mp4cb); + fclose(mp4File); + return (0); + } + } + else + { + aufile = open_audio_file(sndfile, samplerate, frameInfo.channels, + opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo)); + + if (aufile == NULL) + { + NeAACDecClose(hDecoder); + mp4ff_close(infile); + free(mp4cb); + fclose(mp4File); + return 0; + } + } + first_time = 0; + } + + if ((frameInfo.error == 0) && (frameInfo.samples > 0)) + { + if(opt->decode_mode == 0) + WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples); + else + write_audio_file(aufile, sample_buffer, frameInfo.samples, 0); + } + + if (frameInfo.error > 0) + { + error_handler("Error: %s\n", + NeAACDecGetErrorMessage(frameInfo.error)); + break; + } + if(stop_decoding) + break; + } + + + NeAACDecClose(hDecoder); + + + mp4ff_close(infile); + free(mp4cb); + fclose(mp4File); + + if(opt->decode_mode == 0) + WIN_Audio_close(); + else + { + if (!first_time) + close_audio_file(aufile); + } + + return frameInfo.error; +} + +int str_no_case_comp(char const *str1, char const *str2, unsigned long len) +{ + signed int c1 = 0, c2 = 0; + + while (len--) + { + c1 = tolower(*str1++); + c2 = tolower(*str2++); + + if (c1 == 0 || c1 != c2) + break; + } + + return c1 - c2; +} + +int aac_decode(aac_dec_opt *opt) +{ + int result; + int def_srate = 0; + int outfile_set = 0; + int mp4file = 0; + char *fnp; + char audioFileName[MAX_PATH]; + unsigned char header[8]; + FILE *hMP4File; + + + /* point to the specified file name */ + strcpy(audioFileName, opt->filename); + fnp = (char *)strrchr(audioFileName,'.'); + if (fnp) + fnp[0] = '\0'; + strcat(audioFileName, file_ext[opt->file_type]); + + mp4file = 0; + hMP4File = fopen(opt->filename, "rb"); + if (!hMP4File) + { + return 1; + } + fread(header, 1, 8, hMP4File); + fclose(hMP4File); + if (header[4] == 'f' && header[5] == 't' && header[6] == 'y' && header[7] == 'p') + mp4file = 1; + + if (mp4file) + { + result = decodeMP4file(audioFileName, opt); + } + else + { + result = decodeAACfile(audioFileName, def_srate, opt); + } + + return 0; +} diff --git a/faad2/src/aacDECdrop/decode.h b/faad2/src/aacDECdrop/decode.h new file mode 100644 index 0000000..fda27a0 --- /dev/null +++ b/faad2/src/aacDECdrop/decode.h @@ -0,0 +1,55 @@ +/* + * function: Header file for aacDECdrop + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + */ + +#ifndef __DECODE_H__ +#define __DECODE_H__ + +#include + +typedef void (*progress_func)(long totalsamples, long samples); +typedef void (*error_func)(char *errormessage); + +typedef struct +{ + progress_func progress_update; + error_func error; + int decode_mode; + int output_format; + int file_type; + int object_type; + char *filename; +} aac_dec_opt; + + +int aac_decode(aac_dec_opt *opt); + +/* + * Put this here for convenience + */ + +typedef struct { + char TitleFormat[32]; + int window_x; + int window_y; + int always_on_top; + int logerr; + int decode_mode; + int outputFormat; + int fileType; + int object_type; +} SettingsAAC; + +/* + * GLOBALS + */ + +extern SettingsAAC iniSettings; + + +#endif /* __DECODE_H__ */ diff --git a/faad2/src/aacDECdrop/decthread.c b/faad2/src/aacDECdrop/decthread.c new file mode 100644 index 0000000..7ffc3dc --- /dev/null +++ b/faad2/src/aacDECdrop/decthread.c @@ -0,0 +1,194 @@ +/* + * function: Decoding thread for aacDECdrop + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + * + * last mod: aacDecdrop decoder last updated 2002-03-14 + */ + +#include +#include +#include + +#include "wave_out.h" +#include "decode.h" +#include "misc.h" + +extern int decoding_done; +extern int animate; +extern double file_complete; +extern int totalfiles; +extern int numfiles; +int dec_mode; +int outputFormat; +int fileType; +int object_type; +extern char* fileName; +int stop_decoding; + +typedef struct enclist_tag { + char *filename; + struct enclist_tag *next; +} enclist_t; + +enclist_t *head = NULL; + +CRITICAL_SECTION mutex; + +DWORD WINAPI decode_thread(LPVOID arg); + +void decthread_init(void) +{ + int thread_id; + HANDLE thand; + + numfiles = 0; + totalfiles = 0; + file_complete = 0.0; + + InitializeCriticalSection(&mutex); + + thand = CreateThread(NULL, 0, decode_thread, NULL, 0, &thread_id); + if (thand == NULL) { + // something bad happened, might want to deal with that, maybe... + } +} + +void decthread_addfile(char *file) +{ + char *filename; + enclist_t *entry, *node; + + if (file == NULL) return; + + // create entry + filename = strdup(file); + entry = (enclist_t *)malloc(sizeof(enclist_t)); + + entry->filename = filename; + entry->next = NULL; + + EnterCriticalSection(&mutex); + + // insert entry + if (head == NULL) { + head = entry; + } else { + node = head; + while (node->next != NULL) + node = node->next; + + node->next = entry; + } + numfiles++; + totalfiles++; + + LeaveCriticalSection(&mutex); +} + +/* + * the caller is responsible for deleting the pointer + */ + +char *_getfile() +{ + char *filename; + enclist_t *entry; + + EnterCriticalSection(&mutex); + + if (head == NULL) { + LeaveCriticalSection(&mutex); + return NULL; + } + + // pop entry + entry = head; + head = head->next; + + filename = entry->filename; + free(entry); + + LeaveCriticalSection(&mutex); + + return filename; +} + +void decthread_set_decode_mode(int decode_mode) +{ + dec_mode = decode_mode; +} + +void decthread_set_outputFormat(int output_format) +{ + outputFormat = output_format; +} + +void decthread_set_fileType(int file_type) +{ + fileType = file_type; +} + +void decthread_set_object_type(int object_type) +{ + object_type = object_type; +} + +void _error(char *errormessage) +{ + // do nothing +} + +void _update(long total, long done) +{ + file_complete = (double)done / (double)total; +} + +DWORD WINAPI decode_thread(LPVOID arg) +{ + char *in_file; + + while (!decoding_done) + { + while (in_file = _getfile()) + { + aac_dec_opt dec_opts; + animate = 1; + + if(stop_decoding){ + numfiles--; + break; + } + set_filename(in_file); + + dec_opts.progress_update = _update; + dec_opts.filename = in_file; + dec_opts.decode_mode = dec_mode; + dec_opts.output_format = outputFormat; + dec_opts.file_type = fileType; + dec_opts.object_type = object_type; + fileName = in_file; + + aac_decode(&dec_opts); + + numfiles--; + } /* Finished this file, loop around to next... */ + + file_complete = 0.0; + animate = 0; + totalfiles = 0; + numfiles = 0; + + Sleep(500); + } + + DeleteCriticalSection(&mutex); + + return 0; +} + +/******************************** end of decthread.c ********************************/ + diff --git a/faad2/src/aacDECdrop/decthread.h b/faad2/src/aacDECdrop/decthread.h new file mode 100644 index 0000000..90ef374 --- /dev/null +++ b/faad2/src/aacDECdrop/decthread.h @@ -0,0 +1,19 @@ +/* + * function: Header file for decthread.c + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + */ +#ifndef __DECTHREAD_H__ +#define __DECTHREAD_H__ + +void decthread_init(void); +void decthread_addfile(char *file); +void decthread_set_decode_mode(int decode_mode); +void decthread_set_outputFormat(int output_format); +void decthread_set_fileType(int file_type); +void decthread_set_object_type(int object_type); + +#endif /* __DECTHREAD_H__ */ diff --git a/faad2/src/aacDECdrop/main.c b/faad2/src/aacDECdrop/main.c new file mode 100644 index 0000000..ca5f0c4 --- /dev/null +++ b/faad2/src/aacDECdrop/main.c @@ -0,0 +1,678 @@ +/* + * function: Main control program for aacDECdrop + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + * + * last mod: aacDECdrop decoder last updated 2002-03-14 + */ + +#include +#include +#include +#include +#include + +#include "resource.h" +#include "decthread.h" +#include "decode.h" +#include "misc.h" + +#define LOSHORT(l) ((SHORT)(l)) +#define HISHORT(l) ((SHORT)(((DWORD)(l) >> 16) & 0xFFFF)) + +#define INI_FILE "aacDECdrop.ini" + +#define CREATEFONT(sz) \ + CreateFont((sz), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + VARIABLE_PITCH | FF_SWISS, "") + +HANDLE event = NULL; +int width = 130, height = 130; +RECT bar1, bar2, vbrBR; +int prog1 = 0, prog2 = 0; +int moving = 0; +POINT pt; +HINSTANCE hinst; +int frame = 0; +HBITMAP hbm[12], temp; +HMENU menu; +int decoding_done = 0; +int stop_decoding = 0; +double file_complete; +int totalfiles; +int numfiles; +HWND g_hwnd; +HWND qcwnd; +HFONT font2; +char *fileName; + +SettingsAAC iniSettings; // iniSettings holds the parameters for the aacDECdrop configuration + +int animate = 0; + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +BOOL CALLBACK QCProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) ; + + +/* + * Write the .ini file using the current aacDECdrop settings + */ + +int +WriteIniFile ( const char* Filename ) +{ + FILE* fp; + + if ( (fp = fopen (Filename, "w")) == NULL ) + return EOF; // could not open file + + fprintf (fp, "[aacDECdrop]\n"); + fprintf (fp, "Window_X=%i\n" , iniSettings.window_x ); + fprintf (fp, "Window_Y=%i\n" , iniSettings.window_y ); + fprintf (fp, "Always_on_top=%i\n" , iniSettings.always_on_top); + fprintf (fp, "Logerr=%i\n" , iniSettings.logerr ); + fprintf (fp, "DecodeMode=%i\n" , iniSettings.decode_mode ); + fprintf (fp, "OutputFormat=%i\n" , iniSettings.outputFormat ); + fprintf (fp, "FileType=%i\n" , iniSettings.fileType ); + fprintf (fp, "ObjectType=%i\n" , iniSettings.object_type ); + return fclose (fp); +} + +/* + * Read the .ini file and set the aacDECdrop settings + */ + +int +ReadIniFile ( FILE* fp ) +{ + char buff [256]; + int val; + + rewind ( fp ); + fgets ( buff, sizeof buff, fp ); + + if ( 0 != memcmp ( buff, "[aacDECdrop]", 12 ) ) + return EOF; + + while ( fgets ( buff, sizeof buff, fp ) != NULL ) { + if ( 1 == sscanf ( buff, "Window_X=%d" , &val ) ) iniSettings.window_x = val; + else if ( 1 == sscanf ( buff, "Window_Y=%d" , &val ) ) iniSettings.window_y = val; + else if ( 1 == sscanf ( buff, "Always_on_top=%d", &val ) ) iniSettings.always_on_top = val; + else if ( 1 == sscanf ( buff, "Logerr=%d" , &val ) ) iniSettings.logerr = val; + else if ( 1 == sscanf ( buff, "DecodeMode=%d" , &val ) ) iniSettings.decode_mode = val; + else if ( 1 == sscanf ( buff, "OutputFormat=%d" , &val ) ) iniSettings.outputFormat = val; + else if ( 1 == sscanf ( buff, "FileType=%d" , &val ) ) iniSettings.fileType = val; + else if ( 1 == sscanf ( buff, "ObjectType=%d" , &val ) ) iniSettings.object_type = val; + } + + return 0; +} + + +/* + * Get aacDECdrop settings at startup, writes .ini file, if not present + */ + +void +GetAACdecSettings ( void ) +{ + FILE* fp = NULL; + char PathAndName [] = {INI_FILE}; + + // set default values + iniSettings.window_x = 64; // default box position (x co-ord) + iniSettings.window_y = 64; // default box position (y co-ord) + iniSettings.always_on_top = 8; // default = on + iniSettings.logerr = 0; // default = off + iniSettings.decode_mode = 1; // default = 1 (decode to file) + iniSettings.outputFormat = 1; // default = 1 (16 bit PCM) + iniSettings.fileType = 1; // default = 1 (Microsoft WAV) + iniSettings.object_type = 1; // default = 1 (Low Complexity) + + // Read INI_FILE + if ( (fp = fopen (PathAndName, "r")) == NULL ) { // file does not exist: write it! + WriteIniFile ( PathAndName ); + } + else { // file does exist: read it! + ReadIniFile (fp); + fclose (fp); + } + + return; +} + +void set_always_on_top(HWND hwnd, int v) +{ + CheckMenuItem(menu, IDM_ONTOP, v ? MF_CHECKED : MF_UNCHECKED); + SetWindowPos(hwnd, v ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOMOVE); + iniSettings.always_on_top = v; +} + +void set_logerr(HWND hwnd, int v) +{ + CheckMenuItem(menu, IDM_LOGERR, v ? MF_CHECKED : MF_UNCHECKED); + iniSettings.logerr = v; + set_use_dialogs(v); +} + +void set_decode_mode(int v) +{ + decthread_set_decode_mode(v); + iniSettings.decode_mode = v; +} + +void set_outputFormat(int v) +{ + decthread_set_outputFormat(v); + iniSettings.outputFormat = v; +} + +void set_fileType(int v) +{ + decthread_set_fileType(v); + iniSettings.fileType = v; +} + +void set_object_type(int v) +{ + decthread_set_object_type(v); + iniSettings.object_type = v; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) +{ + static char szAppName[] = "aacDECdrop"; + HWND hwnd; + MSG msg; + WNDCLASS wndclass; + const int width = 130; + const int height = 130; + int x; + int y; + + hinst = hInstance; + + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInstance; + wndclass.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_ICON1)); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szAppName; + + RegisterClass(&wndclass); + + GetAACdecSettings(); + + x = max(min(iniSettings.window_x, GetSystemMetrics(SM_CXSCREEN) - width), 0); + y = max(min(iniSettings.window_y, GetSystemMetrics(SM_CYSCREEN) - height), 0); + + hwnd = CreateWindow(szAppName, "aacDECdrop", WS_POPUP | WS_DLGFRAME, x, y, + width, height, NULL, NULL, hInstance, NULL); + + g_hwnd = hwnd; + + ShowWindow(hwnd, iCmdShow); + UpdateWindow(hwnd); + + font2 = CREATEFONT(10); + + SetTimer(hwnd, 1, 80, NULL); + + set_always_on_top(hwnd, iniSettings.always_on_top); + set_logerr(hwnd, iniSettings.logerr); + set_decode_mode(iniSettings.decode_mode); + set_outputFormat(iniSettings.outputFormat); + set_fileType(iniSettings.fileType); + set_object_type(iniSettings.object_type); + + for (frame = 0; frame < 8; frame++) + hbm[frame] = LoadImage(hinst, MAKEINTRESOURCE(IDB_TF01 + frame), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); + frame = 0; + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + for (frame = 0; frame < 8; frame++) + DeleteObject(hbm[frame]); + + return msg.wParam; +} + +void HandleDrag(HWND hwnd, HDROP hDrop) +{ + int cFiles, i; + char szFile[MAX_PATH]; + char *ext; + int flag = 0; + + cFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); + for (i = 0; i < cFiles; i++) + { + DragQueryFile(hDrop, i, szFile, sizeof(szFile)); + + if (ext = strrchr(szFile, '.')) + { + if (stricmp(ext, ".aac") == 0 || stricmp(ext, ".mp4") == 0 || + stricmp(ext, ".m4a") == 0 || stricmp(ext, ".m4p") == 0) + { + flag = 1; + decthread_addfile(szFile); + stop_decoding = 0; + } + } + } + + DragFinish(hDrop); + + if (flag) + SetEvent(event); +} + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + HDC hdc, hmem; + static HDC offscreen; + PAINTSTRUCT ps; + RECT rect, rect2; + BITMAP bm; + POINT point; + static POINT start; + static int dragging = 0; + HDC desktop; + HBITMAP hbitmap; + HANDLE hdrop; + HFONT dfltFont; + int dfltBGMode; + double percomp; + + switch (message) + { + case WM_CREATE: + menu = LoadMenu(hinst, MAKEINTRESOURCE(IDR_MENU1)); + menu = GetSubMenu(menu, 0); + + offscreen = CreateCompatibleDC(NULL); + desktop = GetDC(GetDesktopWindow()); + hbitmap = CreateCompatibleBitmap(desktop, 200, 200); + ReleaseDC(GetDesktopWindow(), desktop); + SelectObject(offscreen, hbitmap); + + // Start the engines + decthread_init(); + + // We accept drag&drop + DragAcceptFiles(hwnd, TRUE); + return 0; + + case WM_PAINT: + hdc = BeginPaint(hwnd, &ps); + GetClientRect(hwnd, &rect); + width = rect.right + 1; + height = rect.bottom + 1; + + FillRect(offscreen, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + DrawText(offscreen, "Drop Files Here", -1, &rect, DT_SINGLELINE | DT_CENTER); + SetRect(&rect2, 0, height - 110, width, height - 25); + DrawText(offscreen, "For Decoding", -1, &rect2, DT_SINGLELINE | DT_CENTER); + + hmem = CreateCompatibleDC(offscreen); + SelectObject(hmem, hbm[frame]); + GetObject(hbm[frame], sizeof(BITMAP), &bm); + BitBlt(offscreen, width / 2 - 33, height / 2 - 31, bm.bmWidth, bm.bmHeight, hmem, 0, 0, SRCCOPY); + DeleteDC(hmem); + + percomp = ((double)(totalfiles - numfiles) + 1 - (1 - file_complete)) / (double)totalfiles; + + SetRect(&vbrBR, 0, height - 35, width, height - 19); + + dfltBGMode = SetBkMode(offscreen, TRANSPARENT); + dfltFont = SelectObject(offscreen, font2); + + SetRect(&bar1, 0, height - 23, (int)(file_complete * width), height - 13); + SetRect(&bar2, 0, height - 12, (int)(percomp * width), height - 2); + + FillRect(offscreen, &bar1, (HBRUSH)GetStockObject(LTGRAY_BRUSH)); + FillRect(offscreen, &bar2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); + + if (fileName) + { + char* sep; + char fileCaption[80]; + + if ((sep = strrchr(fileName, '\\')) != 0) + fileName = sep+1; + + (void) strcpy(fileCaption, " "); + (void) strcat(fileCaption, fileName); + + DrawText(offscreen, fileCaption, -1, &bar1, DT_SINGLELINE | DT_LEFT); + } + + SelectObject(offscreen, dfltFont); + SetBkMode(offscreen, dfltBGMode); + + BitBlt(hdc, 0, 0, width, height, offscreen, 0, 0, SRCCOPY); + + EndPaint(hwnd, &ps); + + return DefWindowProc(hwnd, message, wParam, lParam); + //return 0; + + case WM_TIMER: + if (animate || frame) + { + frame++; + if (frame > 7) + frame -= 8; + } + else + { + frame = 0; + } + GetClientRect(hwnd, &rect); + InvalidateRect(hwnd, &rect, FALSE); + return 0; + + case WM_LBUTTONDOWN: + start.x = LOWORD(lParam); + start.y = HIWORD(lParam); + ClientToScreen(hwnd, &start); + GetWindowRect(hwnd, &rect); + start.x -= rect.left; + start.y -= rect.top; + dragging = 1; + SetCapture(hwnd); + return 0; + + case WM_LBUTTONUP: + if (dragging) + { + dragging = 0; + ReleaseCapture(); + } + return 0; + + case WM_MOUSEMOVE: + if (dragging) + { + point.x = LOSHORT(lParam); + point.y = HISHORT(lParam); + + /* lParam can contain negative coordinates ! + * point.x = LOWORD(lParam); + * point.y = HIWORD(lParam); + */ + + ClientToScreen(hwnd, &point); + SetWindowPos(hwnd, 0, point.x - start.x, point.y - start.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + iniSettings.window_x = point.x - start.x; + iniSettings.window_y = point.y - start.y; + } + return 0; + + case WM_CAPTURECHANGED: + if (dragging) + { + dragging = 0; + ReleaseCapture(); + } + return 0; + + case WM_RBUTTONUP: + point.x = LOWORD(lParam); + point.y = HIWORD(lParam); + ClientToScreen(hwnd, &point); + TrackPopupMenu(menu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL); + return 0; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDM_QUIT: + WriteIniFile(INI_FILE); + decoding_done = 1; + PostQuitMessage(0); + break; + case IDM_ONTOP: + set_always_on_top(hwnd, ~GetMenuState(menu, LOWORD(wParam), MF_BYCOMMAND) & MF_CHECKED); + break; + case IDM_LOGERR: + set_logerr(hwnd, ~GetMenuState(menu, LOWORD(wParam), MF_BYCOMMAND) & MF_CHECKED); + break; + case IDM_STOP_DEC: + { + int v = ~GetMenuState(menu, LOWORD(wParam), MF_BYCOMMAND) & MF_CHECKED; + if(v == 8) + stop_decoding = 1; + break; + } + case IDM_VOLUME: + { + int value = + DialogBox( + hinst, + MAKEINTRESOURCE(IDD_VOLUME), + hwnd, QCProc); + + if (value == -2) + break; + break; + } + case IDM_ABOUT: + { + int value = DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUT), hwnd, QCProc); + if (value == -7) + break; + break; + } + + } // LOWORD(wParam) + return 0; + + case WM_DROPFILES: + hdrop = (HANDLE)wParam; + HandleDrag(hwnd, hdrop); + return 0; + + case WM_DESTROY: + decoding_done = 1; + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + +/* + * Encode parameters dialog procedures. + */ + +BOOL CALLBACK QCProc(HWND hwndDlg, UINT message, + WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + + if(iniSettings.decode_mode == 0) + { + CheckDlgButton(hwndDlg,IDC_PLAYBACK,TRUE); + CheckDlgButton(hwndDlg,IDC_WAV,TRUE); + if(iniSettings.outputFormat != 1 + && iniSettings.outputFormat != 5 + && iniSettings.outputFormat != 6 + && iniSettings.outputFormat != 7 + && iniSettings.outputFormat != 8) + CheckDlgButton(hwndDlg,IDC_16BIT,TRUE); + else if(iniSettings.outputFormat == 1) + CheckDlgButton(hwndDlg,IDC_16BIT,TRUE); + else if(iniSettings.outputFormat == 5) + CheckDlgButton(hwndDlg,IDC_16BIT_DITHER,TRUE); + else if(iniSettings.outputFormat == 6) + CheckDlgButton(hwndDlg,IDC_16BIT_L_SHAPE,TRUE); + else if(iniSettings.outputFormat == 7) + CheckDlgButton(hwndDlg,IDC_16BIT_M_SHAPE,TRUE); + else if(iniSettings.outputFormat == 8) + CheckDlgButton(hwndDlg,IDC_16BIT_H_SHAPE,TRUE); + CheckDlgButton(hwndDlg,IDC_WAV,TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_AIFF), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SUNAU), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DECAU), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_24BIT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_32BIT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_FLOATS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_DITHER), TRUE); + } + else if(iniSettings.decode_mode == 1) + { + CheckDlgButton(hwndDlg,IDC_PLAYBACK,FALSE); + if(iniSettings.outputFormat == 1) + CheckDlgButton(hwndDlg,IDC_16BIT,TRUE); + else if(iniSettings.outputFormat == 2) + CheckDlgButton(hwndDlg,IDC_24BIT,TRUE); + else if(iniSettings.outputFormat == 3) + CheckDlgButton(hwndDlg,IDC_32BIT,TRUE); + else if(iniSettings.outputFormat == 4) + CheckDlgButton(hwndDlg,IDC_FLOATS,TRUE); + else if(iniSettings.outputFormat == 5) + CheckDlgButton(hwndDlg,IDC_16BIT_DITHER,TRUE); + else if(iniSettings.outputFormat == 6) + CheckDlgButton(hwndDlg,IDC_16BIT_L_SHAPE,TRUE); + else if(iniSettings.outputFormat == 7) + CheckDlgButton(hwndDlg,IDC_16BIT_M_SHAPE,TRUE); + else if(iniSettings.outputFormat == 8) + CheckDlgButton(hwndDlg,IDC_16BIT_H_SHAPE,TRUE); + + if(iniSettings.fileType == 1) + CheckDlgButton(hwndDlg,IDC_WAV,TRUE); + else if(iniSettings.fileType == 2) + CheckDlgButton(hwndDlg,IDC_AIFF,TRUE); + else if(iniSettings.fileType == 3) + CheckDlgButton(hwndDlg,IDC_SUNAU,TRUE); + else if(iniSettings.fileType == 4) + CheckDlgButton(hwndDlg,IDC_DECAU,TRUE); + } + + if(iniSettings.object_type == 0) + CheckDlgButton(hwndDlg,IDC_MAIN,TRUE); + else if(iniSettings.object_type == 1) + CheckDlgButton(hwndDlg,IDC_LC,TRUE); + else if(iniSettings.object_type == 3) + CheckDlgButton(hwndDlg,IDC_LTP,TRUE); + else if(iniSettings.object_type == 23) + CheckDlgButton(hwndDlg,IDC_LD,TRUE); + break; + + case WM_CLOSE: + EndDialog(hwndDlg, -1); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_BUTTON1: + { + if (IsDlgButtonChecked(hwndDlg, IDC_PLAYBACK) == BST_CHECKED) + set_decode_mode(0); // Playback + else if (IsDlgButtonChecked(hwndDlg, IDC_DECODE) == BST_CHECKED) + set_decode_mode(1); // Decode to File + + if (IsDlgButtonChecked(hwndDlg, IDC_WAV) == BST_CHECKED) + set_fileType(1); // Microsoft WAV + else if (IsDlgButtonChecked(hwndDlg, IDC_AIFF) == BST_CHECKED) + set_fileType(2); // Apple/SGI AIFF + else if (IsDlgButtonChecked(hwndDlg, IDC_SUNAU) == BST_CHECKED) + set_fileType(3); // Sun/NeXT AU + else if (IsDlgButtonChecked(hwndDlg, IDC_DECAU) == BST_CHECKED) + set_fileType(4); // DEC AU + + if (IsDlgButtonChecked(hwndDlg, IDC_16BIT) == BST_CHECKED) + set_outputFormat(1); // 16 bit PCM + else if (IsDlgButtonChecked(hwndDlg, IDC_24BIT) == BST_CHECKED) + set_outputFormat(2); // 24 bit PCM + else if (IsDlgButtonChecked(hwndDlg, IDC_32BIT) == BST_CHECKED) + set_outputFormat(3); // 32 bit PCM + else if (IsDlgButtonChecked(hwndDlg, IDC_FLOATS) == BST_CHECKED) + set_outputFormat(4); // 32 bit floats + else if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_DITHER) == BST_CHECKED) + set_outputFormat(5); // 16 bit PCM dithered + else if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_L_SHAPE) == BST_CHECKED) + set_outputFormat(6); // dithered LIGHT noise shaping + else if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_M_SHAPE) == BST_CHECKED) + set_outputFormat(7); // dithered MEDIUM noise shaping + else if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_H_SHAPE) == BST_CHECKED) + set_outputFormat(8); // dithered HEAVY noise shaping + + if (IsDlgButtonChecked(hwndDlg, IDC_MAIN) == BST_CHECKED) + set_object_type(0); // Main + else if (IsDlgButtonChecked(hwndDlg, IDC_LC) == BST_CHECKED) + set_object_type(1); // Low Complexity + else if (IsDlgButtonChecked(hwndDlg, IDC_LTP) == BST_CHECKED) + set_object_type(3); // Long Term Prediction + else if (IsDlgButtonChecked(hwndDlg, IDC_LD) == BST_CHECKED) + set_object_type(23); // Low Delay + + EndDialog(hwndDlg, -2); + return TRUE; + } + case IDC_BUTTON6: + EndDialog(hwndDlg, -7); + return TRUE; + + case IDC_PLAYBACK: + CheckDlgButton(hwndDlg,IDC_WAV,TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_AIFF), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SUNAU), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DECAU), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_24BIT), FALSE); + CheckDlgButton(hwndDlg,IDC_24BIT,FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_32BIT), FALSE); + CheckDlgButton(hwndDlg,IDC_32BIT,FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_FLOATS), FALSE); + CheckDlgButton(hwndDlg,IDC_FLOATS,FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_DITHER), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_L_SHAPE), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_M_SHAPE), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_H_SHAPE), TRUE); + if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_DITHER) != BST_CHECKED + && IsDlgButtonChecked(hwndDlg, IDC_16BIT_L_SHAPE) != BST_CHECKED + && IsDlgButtonChecked(hwndDlg, IDC_16BIT_M_SHAPE) != BST_CHECKED + && IsDlgButtonChecked(hwndDlg, IDC_16BIT_H_SHAPE) != BST_CHECKED) + CheckDlgButton(hwndDlg,IDC_16BIT,TRUE); + break; + case IDC_DECODE: + EnableWindow(GetDlgItem(hwndDlg, IDC_AIFF), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SUNAU), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DECAU), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_24BIT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_32BIT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_FLOATS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_DITHER), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_L_SHAPE), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_M_SHAPE), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_H_SHAPE), TRUE); + break; + default: + break; + } + } + return FALSE; +} + + +/******************************** end of main.c ********************************/ + diff --git a/faad2/src/aacDECdrop/misc.c b/faad2/src/aacDECdrop/misc.c new file mode 100644 index 0000000..cf5b9af --- /dev/null +++ b/faad2/src/aacDECdrop/misc.c @@ -0,0 +1,124 @@ +/* + * function: Miscellaneous functions for aacDECdrop + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + */ + +#include +#include +#include +#include +#include "misc.h" + +static char *_filename; +void (*error_handler)(const char *fmt, ...) = error_dialog; + +/* + * Set the current input file name. + */ + +void set_filename(char *filename) +{ + _filename = filename; +} + +/* + * Display an error dialog, possibly adding system error information. + */ + +void error_dialog(const char *fmt, ...) +{ + va_list ap; + char msgbuf[1024]; + char *bufp = msgbuf; + + /* A really rough sanity check to protect against blatant buffer overrun */ + if (strlen(fmt) > 750) + { + sprintf(msgbuf, "%s %s", " ", fmt); + } + else + { + if (_filename != NULL && strlen(_filename) < 255) + { + sprintf(msgbuf, "%s: ", _filename); + bufp += strlen(msgbuf); + } + + va_start(ap, fmt); + + vsprintf(bufp, fmt, ap); + + va_end(ap); + + if (errno != 0) + { + bufp = msgbuf + strlen(msgbuf); + sprintf(bufp, " error is %s (%d)", strerror(errno), errno); + errno = 0; + } + } + + MessageBox(NULL, msgbuf, "Error", 0); +} + +void log_error(const char *fmt, ...) +{ + va_list ap; + FILE *fp; + char msgbuf[1024]; + char *bufp = msgbuf; + + /* A really rough sanity check to protect against blatant buffer overrun */ + if (strlen(fmt) > 750) + { + sprintf(msgbuf, "%s %s", " ", fmt); + } + else + { + if (_filename != NULL && strlen(_filename) < 255) + { + sprintf(msgbuf, "%s : ", _filename); + bufp += strlen(msgbuf); + } + + va_start(ap, fmt); + + vsprintf(bufp, fmt, ap); + + va_end(ap); + + if (errno != 0) + { + bufp = msgbuf + strlen(msgbuf); + sprintf(bufp, " error is: %s (%d)", strerror(errno), errno); + errno = 0; + } + } + + va_start(ap, fmt); + + if ((fp = fopen("oggdrop.log", "a")) == (FILE *)NULL) + return; + + fprintf(fp, "%s\n", msgbuf); + fflush(fp); + fclose(fp); + + va_end(ap); +} + +void set_use_dialogs(int use_dialogs) +{ + if (!use_dialogs) + error_handler = error_dialog; + else + error_handler = log_error; +} + + +/******************************** end of misc.c ********************************/ + diff --git a/faad2/src/aacDECdrop/misc.h b/faad2/src/aacDECdrop/misc.h new file mode 100644 index 0000000..800f21c --- /dev/null +++ b/faad2/src/aacDECdrop/misc.h @@ -0,0 +1,25 @@ +/* + * function: Header file for misc.c + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + */ + +#ifndef __MISC_H__ +#define __MISC_H__ + +#include "decode.h" +#include + +void set_filename(char *filename); + +extern void error_dialog(const char *fmt, ...); +extern void log_error(const char *fmt, ...); +extern void set_use_dialogs(int use_dialogs); +extern void (*error_handler)(const char *fmt, ...); + + +#endif /* __MISC_H__ */ + diff --git a/faad2/src/aacDECdrop/resource.h b/faad2/src/aacDECdrop/resource.h new file mode 100644 index 0000000..5a7fad6 --- /dev/null +++ b/faad2/src/aacDECdrop/resource.h @@ -0,0 +1,54 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Script.rc +// +#define IDD_VOLUME 101 +#define IDD_ABOUT 102 +#define IDB_TF01 112 +#define IDB_TF02 113 +#define IDB_TF03 114 +#define IDB_TF04 115 +#define IDB_TF05 116 +#define IDB_TF06 117 +#define IDB_TF07 118 +#define IDB_TF08 119 +#define IDR_MENU1 124 +#define IDI_ICON1 130 +#define IDC_BUTTON1 1001 +#define IDC_PLAYBACK 1005 +#define IDC_DECODE 1008 +#define IDC_WAV 1014 +#define IDC_AIFF 1015 +#define IDC_SUNAU 1016 +#define IDC_DECAU 1017 +#define IDC_16BIT 1018 +#define IDC_24BIT 1020 +#define IDC_32BIT 1021 +#define IDC_FLOATS 1022 +#define IDC_MAIN 1023 +#define IDC_LC 1024 +#define IDC_LTP 1025 +#define IDC_LD 1026 +#define IDC_16BIT_DITHER 1027 +#define IDC_16BIT_L_SHAPE 1028 +#define IDC_16BIT_M_SHAPE 1029 +#define IDC_16BIT_H_SHAPE 1030 +#define IDC_BUTTON6 1033 +#define IDM_VOLUME 40005 +#define IDM_STOP_DEC 40006 +#define IDM_ABOUT 40007 +#define IDM_LOGERR 40008 +#define IDM_ONTOP 40015 +#define IDM_QUIT 40019 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 134 +#define _APS_NEXT_COMMAND_VALUE 40018 +#define _APS_NEXT_CONTROL_VALUE 1031 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/faad2/src/aacDECdrop/resource/AAC01.bmp b/faad2/src/aacDECdrop/resource/AAC01.bmp new file mode 100644 index 0000000..7d85aac Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC01.bmp differ diff --git a/faad2/src/aacDECdrop/resource/AAC01.ico b/faad2/src/aacDECdrop/resource/AAC01.ico new file mode 100644 index 0000000..b382866 Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC01.ico differ diff --git a/faad2/src/aacDECdrop/resource/AAC02.bmp b/faad2/src/aacDECdrop/resource/AAC02.bmp new file mode 100644 index 0000000..33a8a28 Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC02.bmp differ diff --git a/faad2/src/aacDECdrop/resource/AAC03.bmp b/faad2/src/aacDECdrop/resource/AAC03.bmp new file mode 100644 index 0000000..a9258fe Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC03.bmp differ diff --git a/faad2/src/aacDECdrop/resource/AAC04.bmp b/faad2/src/aacDECdrop/resource/AAC04.bmp new file mode 100644 index 0000000..efa68ef Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC04.bmp differ diff --git a/faad2/src/aacDECdrop/resource/AAC05.bmp b/faad2/src/aacDECdrop/resource/AAC05.bmp new file mode 100644 index 0000000..a29c248 Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC05.bmp differ diff --git a/faad2/src/aacDECdrop/resource/AAC06.bmp b/faad2/src/aacDECdrop/resource/AAC06.bmp new file mode 100644 index 0000000..82af819 Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC06.bmp differ diff --git a/faad2/src/aacDECdrop/resource/AAC07.bmp b/faad2/src/aacDECdrop/resource/AAC07.bmp new file mode 100644 index 0000000..ca418e8 Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC07.bmp differ diff --git a/faad2/src/aacDECdrop/resource/AAC08.bmp b/faad2/src/aacDECdrop/resource/AAC08.bmp new file mode 100644 index 0000000..ce60f19 Binary files /dev/null and b/faad2/src/aacDECdrop/resource/AAC08.bmp differ diff --git a/faad2/src/aacDECdrop/wave_out.c b/faad2/src/aacDECdrop/wave_out.c new file mode 100644 index 0000000..02131ab --- /dev/null +++ b/faad2/src/aacDECdrop/wave_out.c @@ -0,0 +1,190 @@ +/* + * function: Support for playing wave files - Win32 - ONLY + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + */ + +#include +#include +#include "wave_out.h" + +#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 , + Ldouble SampleFreq, + Uint BitsPerSample, + Uint Channels ) +{ + 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); + outFormat.nBlockAlign = outFormat.nChannels * outFormat.wBitsPerSample/8; + outFormat.nAvgBytesPerSec = outFormat.nSamplesPerSec * outFormat.nChannels * outFormat.wBitsPerSample/8; + + 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 ); + SetPriorityClass ( GetCurrentProcess (), HIGH_PRIORITY_CLASS ); +// SetPriorityClass ( GetCurrentProcess (), REALTIME_PRIORITY_CLASS ); + 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; +} + + +/******************************** end of wave_out.c ********************************/ + diff --git a/faad2/src/aacDECdrop/wave_out.h b/faad2/src/aacDECdrop/wave_out.h new file mode 100644 index 0000000..9dceea7 --- /dev/null +++ b/faad2/src/aacDECdrop/wave_out.h @@ -0,0 +1,50 @@ +/* + * function: Header file for wave_out.c + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + */ + +#ifndef __WAVE_OUT_H__ +#define __WAVE_OUT_H__ + + +#include +#include + +#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 + +/* + * Simple types + */ + +typedef signed int Int; // at least -32767...+32767, fast type +typedef unsigned int Uint; // at least 0...65535, fast type +typedef long double Ldouble; // most exact floating point format + +/* + * functions for wave_out.c + */ + +Int Set_WIN_Params ( FILE_T dummyFile , Ldouble SampleFreq, Uint BitsPerSample, Uint Channels ); +int WIN_Play_Samples ( const void* buff, size_t len ); +int WIN_Audio_close ( void ); + +#endif /* __WAVE_OUT_H__ */ -- cgit v1.2.3