AUD_Source.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  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 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  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.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*****************************************************************************
  19. ** **
  20. ** Westwood Studios Pacific. **
  21. ** **
  22. ** Confidential Information **
  23. ** Copyright (C) 2000 - All Rights Reserved **
  24. ** **
  25. ******************************************************************************
  26. ** **
  27. ** Project: Dune Emperor **
  28. ** **
  29. ** Module: <module> (<prefix>_) **
  30. ** **
  31. ** Version: $ID$ **
  32. ** **
  33. ** File name: <filename> **
  34. ** **
  35. ** Created by: 04/05/96 TR **
  36. ** **
  37. ** Description: <description> **
  38. ** **
  39. *****************************************************************************/
  40. /*****************************************************************************
  41. ** Includes **
  42. *****************************************************************************/
  43. #include <memory.h>
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <wpaudio/altypes.h>
  47. #include <wpaudio/memory.h>
  48. #include <wpaudio/time.h>
  49. #include <wpaudio/source.h>
  50. #include <wsys/file.h>
  51. //#include "asimp3\mss.h"
  52. //#include "asimp3\mp3dec.h"
  53. // 'assignment within condition expression'.
  54. #pragma warning(disable : 4706)
  55. DBG_DECLARE_TYPE ( AudioSample )
  56. DBG_DECLARE_TYPE ( AudioFormat )
  57. DBG_DECLARE_TYPE ( AudioFrame )
  58. /*****************************************************************************
  59. ** Externals **
  60. *****************************************************************************/
  61. /*****************************************************************************
  62. ** Defines **
  63. *****************************************************************************/
  64. /*****************************************************************************
  65. ** Private Types **
  66. *****************************************************************************/
  67. /*****************************************************************************
  68. ** Private Data **
  69. *****************************************************************************/
  70. //
  71. // Sample rate in samples/second for [MPEG25][MPEG version][value]
  72. //
  73. static const int sample_rate[2][2][4] =
  74. {{
  75. { 22050L,24000L,16000L,22050L },
  76. { 44100L,48000L,32000L,44100L }
  77. },
  78. {
  79. { 11025L,12000L, 8000L,11025L },
  80. { 44100L,48000L,32000L,44100L }
  81. }};
  82. //
  83. // Bit rate in bits/second for [MPEG version][value]
  84. //
  85. static const int bit_rate[2][15] =
  86. {
  87. { 0L,8000L,16000L,24000L,32000L,40000L,48000L,56000L,64000L,80000L,96000L,112000L,128000L,144000L,160000L }
  88. ,
  89. { 0L,32000L,40000L,48000L,56000L,64000L,80000L,96000L,112000L,128000L,160000L,192000L,224000L,256000L,320000L }
  90. };
  91. /*****************************************************************************
  92. ** Public Data **
  93. *****************************************************************************/
  94. const short MSADPCM_StdCoef[7][2] = {
  95. { 256, 0},
  96. { 512,-256},
  97. { 0, 0},
  98. { 192, 64},
  99. { 240, 0},
  100. { 460,-208},
  101. { 392,-232}
  102. };
  103. /*****************************************************************************
  104. ** Private Prototypes **
  105. *****************************************************************************/
  106. /*****************************************************************************
  107. ** Private Functions **
  108. *****************************************************************************/
  109. /*****************************************************************************
  110. ** Public Functions **
  111. *****************************************************************************/
  112. /******************************************************************/
  113. /* */
  114. /* */
  115. /******************************************************************/
  116. AudioSample* AudioCreateSample( uint bytes )
  117. {
  118. AudioSample *sample;
  119. DBG_ASSERT ( bytes > 0 );
  120. ALLOC_STRUCT ( sample, AudioSample );
  121. AudioSampleInit ( sample );
  122. sample->Bytes = bytes;
  123. if ( ! ( sample->Data = ( char *) AudioMemAlloc ( sample->Bytes ) ))
  124. {
  125. goto error;
  126. }
  127. return sample;
  128. error:
  129. if ( sample )
  130. {
  131. AudioSampleDestroy ( sample );
  132. }
  133. return NULL;
  134. }
  135. /******************************************************************/
  136. /* */
  137. /* */
  138. /******************************************************************/
  139. void AudioSampleDestroy ( AudioSample *sample )
  140. {
  141. DBG_ASSERT_TYPE ( sample, AudioSample );
  142. if ( sample->Data )
  143. {
  144. AudioMemFree ( sample->Data );
  145. }
  146. AudioMemFree ( sample );
  147. }
  148. /******************************************************************/
  149. /* */
  150. /* */
  151. /******************************************************************/
  152. void AudioSampleInit ( AudioSample *sample )
  153. {
  154. DBG_ASSERT ( sample != NULL );
  155. DBG_SET_TYPE ( sample, AudioSample );
  156. sample->Data = NULL;
  157. sample->Bytes = 0;
  158. sample->Format = NULL;
  159. sample->Attribs = NULL;
  160. ListInit ( &sample->Frames );
  161. #ifdef _DEBUG
  162. sample->name[0] = 0;
  163. #endif
  164. }
  165. #ifndef IG_FINAL_RELEASE
  166. /******************************************************************/
  167. /* */
  168. /* */
  169. /******************************************************************/
  170. void AudioSampleSetName ( AudioSample *sample, const char *orig_name )
  171. {
  172. int diff;
  173. char *buffer = NULL;
  174. char *name;
  175. DBG_ASSERT_TYPE ( sample, AudioSample );
  176. buffer = (char *) AudioMemAlloc ( strlen ( orig_name ) + 1);
  177. name = buffer;
  178. sample->name[0] = 0;
  179. if ( name )
  180. {
  181. char *ptr;
  182. strcpy ( name, orig_name );
  183. ptr = strrchr ( name, '.' );
  184. if ( ptr )
  185. {
  186. *ptr = 0;
  187. }
  188. ptr = strrchr ( name, '\\' );
  189. if ( ptr )
  190. {
  191. name = ptr + 1;
  192. }
  193. if ( ( diff = (strlen ( name ) - (sizeof(sample->name) - 1))) > 0 )
  194. {
  195. strcpy ( sample->name, "...");
  196. name = name + diff + 3;
  197. strcat ( sample->name, name );
  198. }
  199. else
  200. {
  201. strcpy ( sample->name, name );
  202. }
  203. }
  204. if ( buffer )
  205. {
  206. AudioMemFree ( buffer );
  207. }
  208. }
  209. #endif
  210. /******************************************************************/
  211. /* */
  212. /* */
  213. /******************************************************************/
  214. void AudioSampleAddFrame ( AudioSample *sample, AudioFrame *frame )
  215. {
  216. DBG_ASSERT_TYPE ( sample, AudioSample );
  217. DBG_ASSERT_TYPE ( frame, AudioFrame );
  218. ListAddToTail ( &sample->Frames, &frame->nd );
  219. sample->Bytes += frame->Bytes;
  220. frame->sample = sample;
  221. }
  222. /******************************************************************/
  223. /* */
  224. /* */
  225. /******************************************************************/
  226. AudioFrame* AudioSampleFirstFrame ( AudioSample *sample )
  227. {
  228. DBG_ASSERT_TYPE ( sample, AudioSample );
  229. return (AudioFrame *) ListNodeNext ( &sample->Frames );
  230. }
  231. /******************************************************************/
  232. /* */
  233. /* */
  234. /******************************************************************/
  235. void AudioSampleDeinit ( AudioSample *sample )
  236. {
  237. DBG_ASSERT_TYPE ( sample, AudioSample );
  238. DBG_INVALIDATE_TYPE ( sample );
  239. }
  240. /******************************************************************/
  241. /* */
  242. /* */
  243. /******************************************************************/
  244. int AudioFormatBytes ( AudioFormat *format, TimeStamp time )
  245. {
  246. DBG_ASSERT_TYPE ( format, AudioFormat );
  247. return (int) ( ((TimeStamp)format->BytesPerSecond*time)/(TimeStamp)SECONDS(1));
  248. }
  249. /******************************************************************/
  250. /* */
  251. /* */
  252. /******************************************************************/
  253. TimeStamp AudioFormatTime ( AudioFormat *format, int bytes )
  254. {
  255. DBG_ASSERT_TYPE ( format, AudioFormat );
  256. if ( format->BytesPerSecond )
  257. {
  258. return (((TimeStamp)bytes)*(TimeStamp)SECONDS(1))/(TimeStamp)format->BytesPerSecond;
  259. }
  260. return 0;
  261. }
  262. /******************************************************************/
  263. /* */
  264. /* */
  265. /******************************************************************/
  266. void AudioFormatInit ( AudioFormat *format )
  267. {
  268. DBG_ASSERT ( format != NULL );
  269. memset ( format, 0, sizeof ( AudioFormat));
  270. DBG_SET_TYPE ( format, AudioFormat );
  271. }
  272. /******************************************************************/
  273. /* */
  274. /* */
  275. /******************************************************************/
  276. void AudioFormatUpdate ( AudioFormat *format )
  277. {
  278. DBG_ASSERT_TYPE ( format, AudioFormat );
  279. DBG_ASSERT ( format->Channels != 0 );
  280. DBG_ASSERT ( format->SampleWidth >0 );
  281. DBG_ASSERT ( format->Rate >0 );
  282. DBG_ASSERT ( format->Compression < AUDIO_COMPRESS_MAX_ID );
  283. if ( format->Compression != AUDIO_COMPRESS_MP3 )
  284. {
  285. format->BytesPerSecond = format->Channels*format->SampleWidth*format->Rate;
  286. if ( format->Compression == AUDIO_COMPRESS_IMA_ADPCM
  287. || format->Compression == AUDIO_COMPRESS_MS_ADPCM )
  288. {
  289. format->BytesPerSecond >>= 2; // 4:1 compression
  290. }
  291. }
  292. else
  293. {
  294. int mpeg1 = (W_BitsGet ( format->cdata.mp3.Header, 1, 19 ));
  295. int bitrateindex = W_BitsGet ( format->cdata.mp3.Header, 4, 12 );
  296. format->BytesPerSecond = bit_rate[mpeg1][bitrateindex] / 8;
  297. }
  298. }
  299. /******************************************************************/
  300. /* */
  301. /* */
  302. /******************************************************************/
  303. void AudioFrameInit ( AudioFrame *frame, void *data, int bytes )
  304. {
  305. DBG_ASSERT_PTR ( frame );
  306. DBG_SET_TYPE ( frame, AudioFrame );
  307. frame->Bytes = bytes;
  308. frame->Data = data;
  309. ListNodeInit ( &frame->nd );
  310. frame->sample = NULL;
  311. }
  312. /******************************************************************/
  313. /* */
  314. /* */
  315. /******************************************************************/
  316. void AudioFrameDeinit ( AudioFrame *frame )
  317. {
  318. DBG_ASSERT_TYPE ( frame, AudioFrame );
  319. frame->sample = NULL;
  320. DBG_INVALIDATE_TYPE ( frame );
  321. }
  322. /******************************************************************/
  323. /* */
  324. /* */
  325. /******************************************************************/
  326. #define MAX_SYNC_SEARCH (10*1024) // max bytes that will be searched for the sync
  327. int AudioFormatReadMP3File ( File *file, AudioFormat *format, int *datasize )
  328. {
  329. unsigned char buffer[MAX_SYNC_SEARCH+3];
  330. int bytes;
  331. int pos;
  332. unsigned int header = 0;
  333. int bitrateindex = 0; // initialize to prevent compiler warning
  334. int sampling_frequency = 0; // initialize to prevent compiler warning
  335. int layer;
  336. int data_start = file->position ();
  337. bytes = file->read ( buffer, sizeof (buffer ));
  338. pos = 0;
  339. while ( !header && bytes >= 4 )
  340. {
  341. unsigned char mask = 0xFF;
  342. // find next sync
  343. while ( bytes >= 3 )
  344. {
  345. if ( (buffer[pos]&mask) == mask )
  346. {
  347. if ( mask == 0xE0 )
  348. {
  349. pos--;
  350. bytes++;
  351. //header = (buffer[pos] << 24) || (buffer[pos+1] << 16) || (buffer[pos+2] << 8) || buffer[pos+3];
  352. header = MAKEID ( buffer[pos], buffer[pos+1], buffer[pos+2], buffer[pos+3]);
  353. break;
  354. }
  355. mask = 0xE0;
  356. }
  357. else
  358. {
  359. mask = 0xFF;
  360. }
  361. pos++;
  362. bytes--;
  363. }
  364. // validate the header
  365. bitrateindex = W_BitsGet ( header, 4, 12 );
  366. sampling_frequency = W_BitsGet ( header, 2, 10 );
  367. layer = (W_BitsGet ( header, 2, 17 ));
  368. if ( bitrateindex == 0x0f || sampling_frequency == 0x03 || layer != 1)
  369. {
  370. header = 0;
  371. pos++;
  372. bytes--;
  373. continue;
  374. }
  375. }
  376. if (!header )
  377. {
  378. return FALSE;
  379. }
  380. int mpeg25 = !(W_BitsGet ( header, 1, 20 ));
  381. int mpeg1 = (W_BitsGet ( header, 1, 19 ));
  382. int mode = (W_BitsGet ( header, 2, 6 ));
  383. format->Compression = AUDIO_COMPRESS_MP3;
  384. format->SampleWidth = 2;
  385. format->Channels = (mode == 3) ? 1 : 2;
  386. format->BytesPerSecond = bit_rate[mpeg1][bitrateindex] / 8;
  387. format->Rate = sample_rate[mpeg25][mpeg1][sampling_frequency];
  388. format->Flags = mAUDIO_FORMAT_PCM;
  389. format->cdata.mp3.Header = header;
  390. AudioFormatUpdate ( format );
  391. if ( datasize )
  392. {
  393. *datasize = file->size() - (data_start + pos) ;
  394. }
  395. file->seek ( data_start+pos, File::START );
  396. return TRUE;
  397. }
  398. /******************************************************************/
  399. /* */
  400. /* */
  401. /******************************************************************/
  402. int AudioFormatSeekToPos ( File *file, const AudioFormat *format, int pos, int data_start )
  403. {
  404. if ( pos )
  405. {
  406. int block_size = 0;
  407. if ( format->Compression == AUDIO_COMPRESS_MP3 )
  408. {
  409. AudioFormat tformat;
  410. file->seek ( pos+data_start, File::START );
  411. AudioFormatInit ( &tformat );
  412. int found = FALSE;
  413. while ( !found )
  414. {
  415. if ( !AudioFormatReadMP3File ( file, &tformat, NULL ) )
  416. {
  417. break;
  418. }
  419. if ( AudioFormatSame ( &tformat, format ) )
  420. {
  421. found = TRUE;
  422. break;
  423. }
  424. file->seek ( 1, File::CURRENT );
  425. }
  426. if ( !found )
  427. {
  428. pos = 0;
  429. }
  430. else
  431. {
  432. pos = file->seek ( 0, File::CURRENT ) - data_start ;
  433. }
  434. }
  435. else
  436. {
  437. switch ( format->Compression )
  438. {
  439. case AUDIO_COMPRESS_NONE:
  440. block_size = format->Channels*format->SampleWidth;
  441. break;
  442. case AUDIO_COMPRESS_IMA_ADPCM:
  443. case AUDIO_COMPRESS_MS_ADPCM:
  444. block_size = format->cdata.adpcm.BlockSize;
  445. break;
  446. }
  447. if ( block_size > 1 )
  448. {
  449. pos = ( pos / block_size ) *block_size;
  450. }
  451. }
  452. }
  453. file->seek ( pos + data_start, File::START );
  454. return pos;
  455. }
  456. /******************************************************************/
  457. /* */
  458. /* */
  459. /******************************************************************/
  460. int AudioFormatSame ( const AudioFormat *f1, const AudioFormat *f2 )
  461. {
  462. if ( (f1->Rate != f2->Rate )
  463. || (f1->Compression != f2->Compression )
  464. || (f1->SampleWidth != f2->SampleWidth )
  465. || (f1->Channels != f2->Channels )
  466. || (f1->Flags != f2->Flags ) )
  467. {
  468. return FALSE;
  469. }
  470. if ( f1->Compression == AUDIO_COMPRESS_IMA_ADPCM && (f1->cdata.adpcm.BlockSize != f2->cdata.adpcm.BlockSize))
  471. {
  472. return FALSE;
  473. }
  474. if ( f1->Compression == AUDIO_COMPRESS_MP3 && (f1->cdata.mp3.Header != f2->cdata.mp3.Header))
  475. {
  476. return FALSE;
  477. }
  478. return TRUE;
  479. }