2
** FAAD - Freeware Advanced Audio Decoder
3
** Copyright (C) 2002 M. Bakker
5
** This program is free software; you can redistribute it and/or modify
6
** it under the terms of the GNU General Public License as published by
7
** the Free Software Foundation; either version 2 of the License, or
8
** (at your option) any later version.
10
** This program is distributed in the hope that it will be useful,
11
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
** GNU General Public License for more details.
15
** You should have received a copy of the GNU General Public License
16
** along with this program; if not, write to the Free Software
17
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
** $Id: in_faad.c,v 1.4 2002/11/01 11:19:36 menno Exp $
22
#define WIN32_LEAN_AND_MEAN
31
#include <filestream.h>
37
static char app_name[] = "AudioCoding.com AAC Player";
39
// post this to the main window at end of file (after playback has stopped)
40
#define WM_WA_AAC_EOF WM_USER+2
42
faadAACInfo file_info;
44
faacDecHandle hDecoder;
45
faacDecFrameInfo frameInfo;
47
In_Module mod; // the output module (declared near the bottom of this file)
48
char *lastfn; // currently playing file (used for getting info on the current file)
49
int file_length; // file length, in bytes
50
int decode_pos_ms; // current decoding position, in milliseconds
51
int paused; // are we paused?
52
int seek_needed; // if != -1, it is the point that the decode thread should seek to, in ms.
54
char *sample_buffer; // sample buffer
55
unsigned char *buffer; // input buffer
56
unsigned char *memmap_buffer; // input buffer for whole file
59
long buffercount, fileread, bytecount;
61
// seek table for ADTS header files
62
unsigned long *seek_table = NULL;
63
int seek_table_length=0;
65
int killPlayThread=0; // the kill switch for the decode thread
66
int PlayThreadAlive=0; // 1=play thread still running
67
HANDLE play_thread_handle=INVALID_HANDLE_VALUE; // the handle to the decode thread
70
/* Function definitions */
71
int id3v2_tag(unsigned char *buffer);
72
DWORD WINAPI PlayThread(void *b); // the decode thread procedure
74
BOOL CALLBACK config_dialog_proc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
77
// 1= use vbr display, 0 = use average bitrate. This value only controls what shows up in the
78
// configuration form. Also- Streaming uses an on-the-fly bitrate display regardless of this value.
79
long m_variable_bitrate_display=0;
81
long m_memmap_file = 0;
82
char m_format_string[50] = "%1 - %2";
83
static char INI_FILE[MAX_PATH];
85
char *priority_text[] = { "",
86
"Decode Thread Priority: Lowest",
87
"Decode Thread Priority: Lower",
88
"Decode Thread Priority: Normal",
89
"Decode Thread Priority: Higher",
90
"Decode Thread Priority: Highest (default)"
93
long priority_table[] = {0, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST};
95
long current_file_mode = 0;
97
int PlayThread_memmap();
98
int PlayThread_file();
100
static void _r_s(char *name,char *data, int mlen)
104
GetPrivateProfileString(app_name,name,buf,data,mlen,INI_FILE);
106
#define RS(x) (_r_s(#x,x,sizeof(x)))
107
#define WS(x) (WritePrivateProfileString(app_name,#x,x,INI_FILE))
111
static void config_init()
114
GetModuleFileName(NULL,INI_FILE,sizeof(INI_FILE));
116
while (p >= INI_FILE && *p != '.') p--;
122
char variable_bitrate_display[10];
124
char memmap_file[10];
125
char local_buffer_size[10];
126
char stream_buffer_size[10];
130
strcpy(variable_bitrate_display, "1");
131
strcpy(priority, "4");
132
strcpy(memmap_file, "0");
133
strcpy(local_buffer_size, "128");
134
strcpy(stream_buffer_size, "64");
136
RS(variable_bitrate_display);
140
RS(local_buffer_size);
141
RS(stream_buffer_size);
143
m_priority = atoi(priority);
144
m_variable_bitrate_display = atoi(variable_bitrate_display);
145
m_memmap_file = atoi(memmap_file);
146
m_local_buffer_size = atoi(local_buffer_size);
147
m_stream_buffer_size = atoi(stream_buffer_size);
152
char variable_bitrate_display[10];
154
char memmap_file[10];
155
char local_buffer_size[10];
156
char stream_buffer_size[10];
158
itoa(m_priority, priority, 10);
159
itoa(m_variable_bitrate_display, variable_bitrate_display, 10);
160
itoa(m_memmap_file, memmap_file, 10);
161
itoa(m_local_buffer_size, local_buffer_size, 10);
162
itoa(m_stream_buffer_size, stream_buffer_size, 10);
164
WS(variable_bitrate_display);
168
WS(local_buffer_size);
169
WS(stream_buffer_size);
172
void config(HWND hwndParent)
174
DialogBox(mod.hDllInstance, MAKEINTRESOURCE(IDD_CONFIG), hwndParent, config_dialog_proc);
177
BOOL CALLBACK config_dialog_proc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
185
SetDlgItemText(hwndDlg, IDC_FORMAT, m_format_string);
187
/* Set priority slider range and previous position */
188
SendMessage(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER), TBM_SETRANGE, TRUE, MAKELONG(1, 5));
189
SendMessage(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER), TBM_SETPOS, TRUE, m_priority);
190
SetDlgItemText(hwndDlg, IDC_STATIC2, priority_text[m_priority]);
192
/* Put a limit to the amount of characters allowed in the buffer boxes */
193
SendMessage(GetDlgItem(hwndDlg, LOCAL_BUFFER_TXT), EM_LIMITTEXT, 4, 0);
194
SendMessage(GetDlgItem(hwndDlg, STREAM_BUFFER_TXT), EM_LIMITTEXT, 4, 0);
196
if(m_variable_bitrate_display)
197
SendMessage(GetDlgItem(hwndDlg, VARBITRATE_CHK), BM_SETCHECK, BST_CHECKED, 0);
199
SendMessage(GetDlgItem(hwndDlg, IDC_MEMMAP), BM_SETCHECK, BST_CHECKED, 0);
201
itoa(m_local_buffer_size, tmp, 10);
202
SetDlgItemText(hwndDlg, LOCAL_BUFFER_TXT, tmp);
204
itoa(m_stream_buffer_size, tmp, 10);
205
SetDlgItemText(hwndDlg, STREAM_BUFFER_TXT, tmp);
211
/* Thread priority slider moved */
212
if(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER) == (HWND) lParam)
215
tmp = SendMessage(GetDlgItem(hwndDlg, THREAD_PRIORITY_SLIDER), TBM_GETPOS, 0, 0);
221
SetDlgItemText(hwndDlg, IDC_STATIC2, priority_text[m_priority]);
223
if(play_thread_handle)
224
SetThreadPriority(play_thread_handle, priority_table[m_priority]);
232
if(HIWORD(wParam) == BN_CLICKED)
234
if(GetDlgItem(hwndDlg, VARBITRATE_CHK) == (HWND) lParam)
236
/* Variable Bitrate checkbox hit */
237
m_variable_bitrate_display = SendMessage(GetDlgItem(hwndDlg, VARBITRATE_CHK), BM_GETCHECK, 0, 0);
239
if(GetDlgItem(hwndDlg, IDC_MEMMAP) == (HWND) lParam)
241
/* Variable Bitrate checkbox hit */
242
m_memmap_file = SendMessage(GetDlgItem(hwndDlg, IDC_MEMMAP), BM_GETCHECK, 0, 0);
246
switch (LOWORD(wParam))
249
/* User hit OK, save buffer settings (all others are set on command) */
250
GetDlgItemText(hwndDlg, LOCAL_BUFFER_TXT, tmp, 5);
251
m_local_buffer_size = atol(tmp);
253
GetDlgItemText(hwndDlg, STREAM_BUFFER_TXT, tmp, 5);
254
m_stream_buffer_size = atol(tmp);
256
GetDlgItemText(hwndDlg, IDC_FORMAT, m_format_string, 50);
262
/* User hit Cancel or the X, just close without saving buffer settings */
263
EndDialog(hwndDlg, wParam);
270
void about(HWND hwndParent)
272
MessageBox(hwndParent,"AudioCoding.com AAC Player\n"
273
"Compiled on: " __DATE__ "\n"
274
"http://www.audiocoding.com\n"
275
"Copyright 2002 AudioCoding.com",
276
"About AAC Player",MB_OK);
281
char plugin_path[1024];
286
hInstance_for_id3editor = mod.hDllInstance;
288
buffer = (unsigned char*)LocalAlloc(LPTR, 768*2);
289
lastfn = (char*)LocalAlloc(LPTR, 1024*sizeof(char));
291
/* Initialize winsock, necessary for streaming */
297
if (lastfn) LocalFree(lastfn);
298
if (buffer) LocalFree(buffer);
300
/* Deallocate winsock */
307
seek_table_length = 0;
311
int isourfile(char *fn)
314
if(StringComp(fn + strlen(fn) - 3, "aac", 3) == 0)
322
unsigned long samplerate, channels;
324
int play_memmap(char *fn)
328
infile = open_filestream(fn);
333
fileread = filelength_filestream(infile);
335
memmap_buffer = (char*)LocalAlloc(LPTR, fileread);
336
read_buffer_filestream(infile, memmap_buffer, fileread);
339
memmap_index = id3v2_tag(memmap_buffer);
341
hDecoder = faacDecOpen();
343
/* Copy the configuration dialog setting and use it as the default */
344
/* initialize the decoder, and get samplerate and channel info */
346
if ((buffercount = faacDecInit(hDecoder, memmap_buffer + memmap_index,
347
fileread - memmap_index - 1, &samplerate, &channels)) < 0)
349
MessageBox(mod.hMainWindow, "Error opening input file\n", "FAAD Error", MB_OK);
353
memmap_index += buffercount;
360
int play_file(char *fn)
365
ZeroMemory(buffer, 768*2);
367
infile = open_filestream(fn);
372
fileread = filelength_filestream(infile);
374
buffercount = bytecount = 0;
375
read_buffer_filestream(infile, buffer, 768*2);
377
tagsize = id3v2_tag(buffer);
379
/* If we find a tag, run right over it */
385
/* Crude way of doing this, but I believe its fast enough to not make a big difference */
386
close_filestream(infile);
387
infile = open_filestream(fn);
389
for(i=0; i < tagsize; i++)
390
read_byte_filestream(infile);
394
seek_filestream(infile, tagsize, FILE_BEGIN);
399
read_buffer_filestream(infile, buffer, 768*2);
402
hDecoder = faacDecOpen();
404
/* Copy the configuration dialog setting and use it as the default */
405
/* initialize the decoder, and get samplerate and channel info */
407
if((buffercount = faacDecInit(hDecoder, buffer, 768*2, &samplerate, &channels)) < 0)
409
MessageBox(mod.hMainWindow, "Error opening input file\n", "FAAD Error", MB_OK);
415
bytecount += buffercount;
417
for (k = 0; k < (768*2 - buffercount); k++)
418
buffer[k] = buffer[k + buffercount];
420
read_buffer_filestream(infile, buffer + (768*2) - buffercount, buffercount);
434
current_file_mode = m_memmap_file;
436
if (current_file_mode) {
448
seek_table_length = 0;
451
get_AAC_format(fn, &file_info, &seek_table, &seek_table_length, 0);
455
/* No seeking in http streams */
460
if (file_info.headertype == 2) /* ADTS header - seekable */
463
mod.is_seekable = 0; /* ADIF or Headerless - not seekable */
472
To RageAmp: This is really needed, because aacinfo isn't very accurate on ADIF files yet.
473
Can be fixed though :-)
475
file_info.sampling_rate = samplerate;
476
file_info.channels = frameInfo.channels;
478
maxlatency = mod.outMod->Open(file_info.sampling_rate, file_info.channels, 16, -1,-1);
480
if (maxlatency < 0) // error opening device
485
// initialize vis stuff
486
mod.SAVSAInit(maxlatency, file_info.sampling_rate);
487
mod.VSASetInfo(file_info.sampling_rate, file_info.channels);
489
mod.SetInfo(file_info.bitrate/1000, file_info.sampling_rate/1000, file_info.channels,1);
491
mod.outMod->SetVolume(-666); // set the output plug-ins default volume
495
if((play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PlayThread, (void *) &killPlayThread, 0, &thread_id)) == NULL)
497
MessageBox(mod.hMainWindow, "Fatal error: Cannot create playback thread\n", "FAAD Error", MB_OK);
501
// Note: This line seriously slows down start up time
502
if(m_priority != 3) // if the priority in config window is set to normal, there is nothing to reset!
503
SetThreadPriority(play_thread_handle, priority_table[m_priority]);
508
void pause() { paused=1; mod.outMod->Pause(1); }
509
void unpause() { paused=0; mod.outMod->Pause(0); }
510
int ispaused() { return paused; }
516
if (play_thread_handle != INVALID_HANDLE_VALUE)
518
if (WaitForSingleObject(play_thread_handle, INFINITE) == WAIT_TIMEOUT)
519
TerminateThread(play_thread_handle,0);
520
CloseHandle(play_thread_handle);
521
play_thread_handle = INVALID_HANDLE_VALUE;
524
faacDecClose(hDecoder);
525
close_filestream(infile);
529
if (memmap_buffer) LocalFree(memmap_buffer);
534
seek_table_length = 0;
540
return file_info.length;
545
return decode_pos_ms+(mod.outMod->GetOutputTime()-mod.outMod->GetWrittenTime());
548
void setoutputtime(int time_in_ms)
550
if (file_info.headertype == 2)
551
seek_needed=time_in_ms;
556
int aac_seek(int pos_ms, int *sktable)
560
offset_sec = pos_ms / 1000.0;
561
if (!current_file_mode)
563
seek_filestream(infile, sktable[(int)(offset_sec+0.5)], FILE_BEGIN);
565
bytecount = sktable[(int)(offset_sec+0.5)];
567
read_buffer_filestream(infile, buffer, 768*2);
569
memmap_index = sktable[(int)(offset_sec+0.5)];
575
VOID EnableCheckbox(HWND checkBox, BOOL bEnable, BOOL bChecked)
578
EnableWindow(checkBox, TRUE);
579
SendMessage(checkBox, BM_SETCHECK, bChecked?BST_CHECKED:BST_UNCHECKED, 0);
581
EnableWindow(checkBox, FALSE);
582
SendMessage(checkBox, BM_SETCHECK, bChecked?BST_CHECKED:BST_UNCHECKED, 0);
586
void setvolume(int volume) { mod.outMod->SetVolume(volume); }
587
void setpan(int pan) { mod.outMod->SetPan(pan); }
592
BOOL CALLBACK info_dialog_proc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
602
/* Set up the list control for the ID3 tag */
604
/* Initialize the LV_COLUMN structure. */
605
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
606
lvc.fmt = LVCFMT_LEFT;
608
/* Add the columns. */
611
lvc.pszText = "Frame";
612
ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_ID3LIST), 0, &lvc);
615
lvc.pszText = "Data";
616
ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_ID3LIST), 1, &lvc);
619
get_AAC_format(info_fn, &format, NULL, NULL, 1);
621
switch(format.headertype)
623
case 0: /* Headerless */
624
tmp_string = "RAW"; break;
626
tmp_string = "ADIF"; break;
628
tmp_string = "ADTS"; break;
630
SetDlgItemText(hwndDlg, IDC_HEADER, tmp_string);
632
if (format.object_type == 0 /* Main */)
634
else if (format.object_type == 1 /* Low Complexity */)
635
tmp_string = "Low Complexity";
636
else if (format.object_type == 2 /* SSR */)
637
tmp_string = "SSR (unsupported)";
638
else if (format.object_type == 3 /* LTP */)
639
tmp_string = "Main LTP";
640
SetDlgItemText(hwndDlg, IDC_PROFILE, tmp_string);
642
if (format.version == 2) tmp_string = "MPEG2";
643
else tmp_string = "MPEG4";
644
SetDlgItemText(hwndDlg, IDC_VERSION, tmp_string);
646
wsprintf(info, "%d bps", format.bitrate);
647
SetDlgItemText(hwndDlg, IDC_BITRATE, info);
649
wsprintf(info, "%d Hz", format.sampling_rate);
650
SetDlgItemText(hwndDlg, IDC_SAMPLERATE, info);
652
wsprintf(info, "%d ch", format.channels);
653
SetDlgItemText(hwndDlg, IDC_CHANNELS, info);
655
FillID3List(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST), info_fn);
656
if (ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_ID3LIST)) == 0)
657
EnableWindow(GetDlgItem(hwndDlg, IDC_ID3V2TAG), FALSE);
659
EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE);
660
bFileChanged = FALSE;
666
/* Branch depending on the specific notification message. */
667
switch (((LPNMHDR) lParam)->code) {
669
/* Process LVN_GETDISPINFO to supply information about */
670
/* callback items. */
671
case LVN_GETDISPINFO:
672
List_OnGetDispInfo((LV_DISPINFO *)lParam);
675
bResult = List_EditData(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST));
677
EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE);
678
bFileChanged = bFileChanged ? bFileChanged : bResult;
684
switch (LOWORD(wParam)) {
685
case IDC_ADDSTFRAMES:
686
bResult = List_AddStandardFrames(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST));
688
EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE);
689
bFileChanged = bFileChanged ? bFileChanged : bResult;
692
bResult = List_AddFrame(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST));
694
EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE);
695
bFileChanged = bFileChanged ? bFileChanged : bResult;
698
bResult = List_DeleteSelected(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST));
699
if (ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_ID3LIST)) == 0)
700
EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), FALSE, FALSE);
701
bFileChanged = bFileChanged ? bFileChanged : bResult;
704
bResult = List_EditData(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST));
706
EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE);
707
bFileChanged = bFileChanged ? bFileChanged : bResult;
715
if (bFileChanged == TRUE) {
716
if (MessageBox(hwndDlg, "Save changes?", "Save changes", MB_YESNO) == IDYES)
717
List_SaveID3(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST), info_fn);
719
EndDialog(hwndDlg, wParam);
726
int infoDlg(char *fn, HWND hwnd)
728
lstrcpy(info_fn, fn);
730
DialogBox(mod.hDllInstance, MAKEINTRESOURCE(IDD_INFO),
731
hwnd, info_dialog_proc);
736
LPTSTR PathFindFileName(LPCTSTR pPath)
740
for (pT = pPath; *pPath; pPath = CharNext(pPath)) {
741
if ((pPath[0] == TEXT('\\') || pPath[0] == TEXT(':')) && pPath[1] && (pPath[1] != TEXT('\\')))
745
return (LPTSTR)pT; // const -> non const
748
int getsonglength(char *fn)
752
get_AAC_format(fn, &tmp, NULL, NULL, 1);
757
void getfileinfo(char *filename, char *title, int *length_in_ms)
759
if (!filename || !*filename) // currently playing file
762
*length_in_ms=getlength();
765
GetID3FileTitle(lastfn, title, m_format_string);
767
else // some other file
770
*length_in_ms = getsonglength(filename);
773
GetID3FileTitle(filename, title, m_format_string);
777
void eq_set(int on, char data[10], int preamp)
783
int PlayThread_memmap()
785
sample_buffer = (char*)faacDecDecode(hDecoder, &frameInfo,
786
memmap_buffer + memmap_index, fileread - memmap_index - 1);
789
MessageBox(NULL, faacDecGetErrorMessage(frameInfo.error), "FAAD Error", MB_OK);
793
memmap_index += frameInfo.bytesconsumed;
794
if (memmap_index >= fileread)
797
return frameInfo.bytesconsumed;
800
int PlayThread_file()
804
if (buffercount > 0) {
805
for (k = 0; k < (768*2 - buffercount); k++)
806
buffer[k] = buffer[k + buffercount];
808
read_buffer_filestream(infile, buffer + (768*2) - buffercount, buffercount);
812
sample_buffer = (char*)faacDecDecode(hDecoder, &frameInfo, buffer, 768*2);
815
MessageBox(NULL, faacDecGetErrorMessage(frameInfo.error), "FAAD Error", MB_OK);
819
buffercount += frameInfo.bytesconsumed;
821
bytecount += frameInfo.bytesconsumed;
822
if (bytecount >= fileread)
825
return frameInfo.bytesconsumed;
828
DWORD WINAPI PlayThread(void *b)
832
int decoded_frames=0;
833
int br_calc_frames=0;
834
int br_bytes_consumed=0;
835
unsigned long bytesconsumed;
840
while (! *((int *)b) )
842
if (seek_needed != -1)
846
// Round off to a second
847
seconds = seek_needed - (seek_needed%1000);
848
mod.outMod->Flush(decode_pos_ms);
849
aac_seek(seconds, seek_table);
850
decode_pos_ms = seconds;
854
br_bytes_consumed = 0;
859
mod.outMod->CanWrite();
861
if (!mod.outMod->IsPlaying())
863
PostMessage(mod.hMainWindow,WM_WA_AAC_EOF,0,0);
870
//assume that max channels is 2.
871
else if (mod.outMod->CanWrite() >= ((1024*file_info.channels*sizeof(short))<<(mod.dsp_isactive()?1:0)))
879
if (current_file_mode)
880
bytesconsumed = PlayThread_memmap();
882
bytesconsumed = PlayThread_file();
886
br_bytes_consumed += bytesconsumed;
888
/* Update the variable bitrate about every second */
889
if(m_variable_bitrate_display && br_calc_frames == 43)
893
br = (int)((br_bytes_consumed * 8) / (decoded_frames / 43.07));
895
mod.SetInfo(br/1000, file_info.sampling_rate/1000, file_info.channels, 1);
899
if (!killPlayThread && (frameInfo.samples > 0))
901
mod.SAAddPCMData(sample_buffer,file_info.channels, 16, decode_pos_ms);
902
mod.VSAAddPCMData(sample_buffer,file_info.channels, 16, decode_pos_ms);
903
decode_pos_ms+=(1024*1000)/file_info.sampling_rate;
905
if (mod.dsp_isactive())
906
l=mod.dsp_dosamples((short *)sample_buffer,frameInfo.samples*sizeof(short)/file_info.channels/(16/8),16,file_info.channels,file_info.sampling_rate)*(file_info.channels*(16/8));
908
l = frameInfo.samples*sizeof(short);
910
mod.outMod->Write(sample_buffer, l);
924
seek_table_length = 0;
932
int id3v2_tag(unsigned char *buffer)
934
if (StringComp(buffer, "ID3", 3) == 0)
936
unsigned long tagsize;
938
/* high bit is not used */
939
tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
940
(buffer[8] << 7) | (buffer[9] << 0);
955
"AudioCoding.com AAC Player: " __DATE__,
958
"AAC\0AAC File (*.AAC)\0"
982
0,0,0,0,0,0,0,0,0, // vis stuff
994
__declspec( dllexport ) In_Module * winampGetInModule2()