ima4.c
上传用户:luping1608
上传日期:2007-01-06
资源大小:38k
文件大小:13k
源码类别:

多媒体

开发平台:

Unix_Linux

  1. #include "quicktime.h"
  2. static int quicktime_ima4_step[89] = 
  3. {
  4.     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
  5.     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
  6.     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
  7.     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
  8.     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
  9.     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
  10.     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  11.     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  12.     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
  13. };
  14. static int quicktime_ima4_index[16] = 
  15. {
  16.     -1, -1, -1, -1, 2, 4, 6, 8,
  17.     -1, -1, -1, -1, 2, 4, 6, 8
  18. };
  19. // Known by divine revelation
  20. #define BLOCK_SIZE 0x22
  21. #define SAMPLES_PER_BLOCK 0x40
  22. // ================================== private for ima4
  23. // Convert the number of samples in a chunk into the number of bytes in that
  24. // chunk.  The number of samples in a chunk should end on a block boundary.
  25. int ima4_decode_block(quicktime_audio_map_t *atrack, QUICKTIME_INT16 *output, unsigned char *input)
  26. {
  27. int predictor;
  28. int index;
  29. int step;
  30. int i, nibble, nibble_count, block_size;
  31. unsigned char *block_ptr;
  32. unsigned char *input_end = input + BLOCK_SIZE;
  33. quicktime_ima4_codec_t *codec = &(atrack->codecs.ima4_codec);
  34. // Get the chunk header
  35. predictor = *input++ << 8;
  36. predictor |= *input++;
  37. index = predictor & 0x7f;
  38. if(index > 88) index = 88;
  39. predictor &= 0xff80;
  40. if(predictor & 0x8000) predictor -= 0x10000;
  41. step = quicktime_ima4_step[index];
  42. // Read the input buffer sequentially, one nibble at a time
  43. nibble_count = 0;
  44. while(input < input_end)
  45. {
  46. nibble = nibble_count ? (*input++  >> 4) & 0x0f : *input & 0x0f;
  47. ima4_decode_sample(&predictor, &nibble, &index, &step);
  48. *output++ = predictor;
  49. nibble_count ^= 1;
  50. }
  51. }
  52. int ima4_decode_sample(int *predictor, int *nibble, int *index, int *step)
  53. {
  54. int difference, sign;
  55. // Get new index value
  56. *index += quicktime_ima4_index[*nibble];
  57. if(*index < 0) *index = 0; 
  58. else 
  59. if(*index > 88) *index = 88;
  60. // Get sign and magnitude from nibble
  61. sign = *nibble & 8;
  62. *nibble = *nibble & 7;
  63. // Get difference
  64. difference = *step >> 3;
  65. if(*nibble & 4) difference += *step;
  66. if(*nibble & 2) difference += *step >> 1;
  67. if(*nibble & 1) difference += *step >> 2;
  68. // Predict value
  69. if(sign) 
  70. *predictor -= difference;
  71. else 
  72. *predictor += difference;
  73. if(*predictor > 32767) *predictor = 32767;
  74. else
  75. if(*predictor < -32768) *predictor = -32768;
  76. // Update the step value
  77. *step = quicktime_ima4_step[*index];
  78. return 0;
  79. }
  80. int ima4_encode_block(quicktime_audio_map_t *atrack, unsigned char *output, QUICKTIME_INT16 *input, int step, int channel)
  81. {
  82. quicktime_ima4_codec_t *codec = &(atrack->codecs.ima4_codec);
  83. int i, nibble_count = 0, nibble, header;
  84. header = codec->last_samples[channel];
  85. if(header < 0) header += 0x10000;
  86. *output = (header & 0xff00) >> 8;
  87. output++;
  88. *output++ = (header & 0x80) | (codec->last_indexes[channel] & 0x7f);
  89. for(i = 0; i < SAMPLES_PER_BLOCK; i++)
  90. {
  91. ima4_encode_sample(&(codec->last_samples[channel]), 
  92. &(codec->last_indexes[channel]), 
  93. &nibble, 
  94. *input);
  95. if(nibble_count)
  96. *output++ |= (nibble << 4);
  97. else
  98. *output = nibble;
  99. input += step;
  100. nibble_count ^= 1;
  101. }
  102. return 0;
  103. }
  104. int ima4_encode_sample(int *last_sample, int *last_index, int *nibble, int next_sample)
  105. {
  106. int difference, new_difference, mask, step;
  107. difference = next_sample - *last_sample;
  108. *nibble = 0;
  109. step = quicktime_ima4_step[*last_index];
  110. new_difference = step >> 3;
  111. if(difference < 0)
  112. {
  113. *nibble = 8;
  114. difference = -difference;
  115. }
  116. mask = 4;
  117. while(mask)
  118. {
  119. if(difference >= step)
  120. {
  121. *nibble |= mask;
  122. difference -= step;
  123. new_difference += step;
  124. }
  125. step >>= 1;
  126. mask >>= 1;
  127. }
  128. if(*nibble & 8)
  129. *last_sample -= new_difference;
  130. else
  131. *last_sample += new_difference;
  132. if(*last_sample > 32767) *last_sample = 32767;
  133. else
  134. if(*last_sample < -32767) *last_sample = -32767;
  135. *last_index += quicktime_ima4_index[*nibble];
  136. if(*last_index < 0) *last_index = 0;
  137. else
  138. if(*last_index > 88) *last_index= 88;
  139. return 0;
  140. }
  141. long ima4_samples_to_bytes(long samples, int channels)
  142. {
  143. long bytes = samples / SAMPLES_PER_BLOCK * BLOCK_SIZE * channels;
  144. return bytes;
  145. }
  146. // Decode the chunk into the work buffer
  147. int ima4_decode_chunk(quicktime_t *file, int track, long chunk, int channel)
  148. {
  149. int result = 0;
  150. int i, j;
  151. long chunk_samples, chunk_bytes;
  152. unsigned char *chunk_ptr, *block_ptr;
  153. quicktime_trak_t *trak = file->atracks[track].track;
  154. quicktime_ima4_codec_t *codec = &(file->atracks[track].codecs.ima4_codec);
  155. // Get the byte count to read.
  156. chunk_samples = quicktime_chunk_samples(trak, chunk);
  157. chunk_bytes = ima4_samples_to_bytes(chunk_samples, file->atracks[track].channels);
  158. // Get the buffer to read into.
  159. if(codec->work_buffer && codec->work_size < chunk_samples)
  160. {
  161. free(codec->work_buffer);
  162. codec->work_buffer = 0;
  163. }
  164. if(!codec->work_buffer)
  165. {
  166. codec->work_size = chunk_samples;
  167. codec->work_buffer = malloc(sizeof(QUICKTIME_INT16) * codec->work_size);
  168. }
  169. if(codec->read_buffer && codec->read_size < chunk_bytes)
  170. {
  171. free(codec->read_buffer);
  172. codec->read_buffer = 0;
  173. }
  174. if(!codec->read_buffer)
  175. {
  176. codec->read_size = chunk_bytes;
  177. codec->read_buffer = malloc(codec->read_size);
  178. }
  179. // codec->work_size now holds the number of samples in the last chunk
  180. // codec->read_size now holds number of bytes in the last read buffer
  181. // Read the entire chunk regardless of where the desired sample range starts.
  182. result = quicktime_read_chunk(file, codec->read_buffer, track, chunk, 0, chunk_bytes);
  183. // Now decode the chunk, one block at a time, until the total samples in the chunk
  184. // is reached.
  185. if(!result)
  186. {
  187. block_ptr = codec->read_buffer;
  188. for(i = 0; i < chunk_samples; i += SAMPLES_PER_BLOCK)
  189. {
  190. for(j = 0; j < file->atracks[track].channels; j++)
  191. {
  192. if(j == channel)
  193. ima4_decode_block(&(file->atracks[track]), &(codec->work_buffer[i]), block_ptr);
  194. block_ptr += BLOCK_SIZE;
  195. }
  196. }
  197. }
  198. codec->buffer_channel = channel;
  199. codec->chunk = chunk;
  200. return result;
  201. }
  202. // =================================== public for ima4
  203. int quicktime_init_codec_ima4(quicktime_audio_map_t *atrack)
  204. {
  205. quicktime_ima4_codec_t *codec = &(atrack->codecs.ima4_codec);
  206. codec->work_buffer = 0;
  207. codec->read_buffer = 0;
  208. codec->chunk = 0;
  209. codec->buffer_channel = 0;
  210. codec->work_overflow = 0;
  211. codec->work_size = 0;
  212. codec->read_size = 0;
  213. codec->last_samples = 0;
  214. codec->last_indexes = 0;
  215. //printf("quicktime_init_codec_ima4 1 %x %x %xn", atrack, codec, codec->work_buffer);
  216. return 0;
  217. }
  218. int quicktime_delete_codec_ima4(quicktime_audio_map_t *atrack)
  219. {
  220. quicktime_ima4_codec_t *codec = &(atrack->codecs.ima4_codec);
  221. if(codec->work_buffer) free(codec->work_buffer);
  222. if(codec->read_buffer) free(codec->read_buffer);
  223. if(codec->last_samples) free(codec->last_samples);
  224. if(codec->last_indexes) free(codec->last_indexes);
  225. codec->last_samples = 0;
  226. codec->last_indexes = 0;
  227. codec->read_buffer = 0;
  228. codec->work_buffer = 0;
  229. codec->chunk = 0;
  230. codec->buffer_channel = 0; // Channel of work buffer
  231. codec->work_size = 0;          // Size of work buffer
  232. codec->read_size = 0;
  233. return 0;
  234. }
  235. int quicktime_decode_ima4(quicktime_t *file, 
  236. QUICKTIME_INT16 *output_i, 
  237. float *output_f,
  238. long samples, 
  239. int track, 
  240. int channel,
  241. int do_float)
  242. {
  243. int result = 0;
  244. long chunk, chunk_sample, chunk_bytes, chunk_samples;
  245. long i, chunk_start, chunk_end;
  246. quicktime_trak_t *trak = file->atracks[track].track;
  247. quicktime_ima4_codec_t *codec = &(file->atracks[track].codecs.ima4_codec);
  248. // Get the first chunk with this routine and then increase the chunk number.
  249. quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, file->atracks[track].current_position);
  250. // Read chunks and extract ranges of samples until the output is full.
  251. for(i = 0; i < samples && !result; )
  252. {
  253. // Get chunk we're on.
  254. chunk_samples = quicktime_chunk_samples(trak, chunk);
  255. if(!codec->work_buffer ||
  256. codec->chunk != chunk ||
  257. codec->buffer_channel != channel)
  258. {
  259. // read a new chunk if necessary
  260. result = ima4_decode_chunk(file, track, chunk, channel);
  261. }
  262. // Get boundaries from the chunk
  263. chunk_start = 0;
  264. if(chunk_sample < file->atracks[track].current_position)
  265. chunk_start = file->atracks[track].current_position - chunk_sample;
  266. chunk_end = chunk_samples;
  267. if(chunk_sample + chunk_end > file->atracks[track].current_position + samples)
  268. chunk_end = file->atracks[track].current_position + samples - chunk_sample;
  269. // Read from the chunk
  270. if(output_i)
  271. {
  272. //printf("decode_ima4 1 chunk %ld %ld-%ld output %ldn", chunk, chunk_start + chunk_sample, chunk_end + chunk_sample, i);
  273. while(chunk_start < chunk_end)
  274. {
  275. output_i[i++] = codec->work_buffer[chunk_start++];
  276. }
  277. //printf("decode_ima4 2n");
  278. }
  279. else
  280. if(output_f)
  281. {
  282. while(chunk_start < chunk_end)
  283. {
  284. output_f[i++] = (float)codec->work_buffer[chunk_start++] / 32767;
  285. }
  286. }
  287. chunk++;
  288. chunk_sample += chunk_samples;
  289. }
  290. return result;
  291. }
  292. int quicktime_encode_ima4(quicktime_t *file, 
  293. QUICKTIME_INT16 **input_i, 
  294. float **input_f, 
  295. int track, 
  296. long samples)
  297. {
  298. int result = 0;
  299. long i, j, step;
  300. long chunk_bytes;
  301. long overflow_start;
  302. long offset;
  303. long chunk_samples; // Samples in the current chunk to be written
  304. quicktime_audio_map_t *track_map = &(file->atracks[track]);
  305. quicktime_ima4_codec_t *codec = &(track_map->codecs.ima4_codec);
  306. QUICKTIME_INT16 *input_ptr;
  307. unsigned char *output_ptr;
  308. // Get buffer sizes
  309. if(codec->work_buffer && codec->work_size < (samples + codec->work_overflow) * track_map->channels)
  310. {
  311. // Create new buffer
  312. long new_size = (samples + codec->work_overflow) * track_map->channels;
  313. QUICKTIME_INT16 *new_buffer = malloc(sizeof(QUICKTIME_INT16) * new_size);
  314. // Copy overflow
  315. for(i = 0; i < codec->work_overflow * track_map->channels; i++)
  316. new_buffer[i] = codec->work_buffer[i];
  317. // Swap pointers.
  318. free(codec->work_buffer);
  319. codec->work_buffer = new_buffer;
  320. codec->work_size = new_size;
  321. }
  322. else
  323. if(!codec->work_buffer)
  324. {
  325. // No buffer in the first place.
  326. codec->work_size = (samples + codec->work_overflow) * track_map->channels;
  327. codec->work_buffer = malloc(sizeof(QUICKTIME_INT16) * codec->work_size);
  328. }
  329. // Get output size
  330. chunk_bytes = ima4_samples_to_bytes(samples + codec->work_overflow, track_map->channels);
  331. if(codec->read_buffer && codec->read_size < chunk_bytes)
  332. {
  333. free(codec->read_buffer);
  334. codec->read_buffer = 0;
  335. }
  336. if(!codec->read_buffer)
  337. {
  338. codec->read_buffer = malloc(chunk_bytes);
  339. codec->read_size = chunk_bytes;
  340. }
  341. if(!codec->last_samples)
  342. {
  343. codec->last_samples = malloc(sizeof(int) * track_map->channels);
  344. for(i = 0; i < track_map->channels; i++)
  345. {
  346. codec->last_samples[i] = 0;
  347. }
  348. }
  349. if(!codec->last_indexes)
  350. {
  351. codec->last_indexes = malloc(sizeof(int) * track_map->channels);
  352. for(i = 0; i < track_map->channels; i++)
  353. {
  354. codec->last_indexes[i] = 0;
  355. }
  356. }
  357. // Arm the input buffer after the last overflow
  358. step = track_map->channels;
  359. for(j = 0; j < track_map->channels; j++)
  360. {
  361. input_ptr = codec->work_buffer + codec->work_overflow * track_map->channels + j;
  362. if(input_i)
  363. {
  364. for(i = 0; i < samples; i++)
  365. {
  366. *input_ptr = input_i[j][i];
  367. input_ptr += step;
  368. }
  369. }
  370. else
  371. if(input_f)
  372. {
  373. for(i = 0; i < samples; i++)
  374. {
  375. *input_ptr = (QUICKTIME_INT16)(input_f[j][i] * 32767);
  376. input_ptr += step;
  377. }
  378. }
  379. }
  380. // Encode from the input buffer to the read_buffer up to a multiple of 
  381. // blocks.
  382. input_ptr = codec->work_buffer;
  383. output_ptr = codec->read_buffer;
  384. for(i = 0; 
  385. i + SAMPLES_PER_BLOCK <= samples + codec->work_overflow; 
  386. i += SAMPLES_PER_BLOCK)
  387. {
  388. for(j = 0; j < track_map->channels; j++)
  389. {
  390. ima4_encode_block(track_map, output_ptr, input_ptr + j, track_map->channels, j);
  391. output_ptr += BLOCK_SIZE;
  392. }
  393. input_ptr += SAMPLES_PER_BLOCK * track_map->channels;
  394. }
  395. // Write to disk
  396. chunk_samples = (long)((samples + codec->work_overflow) / SAMPLES_PER_BLOCK) * SAMPLES_PER_BLOCK;
  397. // The block division may result in 0 samples getting encoded.
  398. // Don't write 0 samples.
  399. if(chunk_samples)
  400. {
  401. offset = quicktime_position(file);
  402. result = quicktime_write_data(file, codec->read_buffer, chunk_bytes);
  403. if(result) result = 0; else result = 1; // defeat fwrite's return
  404. quicktime_update_tables(track_map->track, 
  405. offset, 
  406. track_map->current_chunk, 
  407. track_map->current_position, 
  408. chunk_samples, 
  409. 0);
  410. file->atracks[track].current_chunk++;
  411. }
  412. // Move the last overflow to the front
  413. overflow_start = i;
  414. input_ptr = codec->work_buffer;
  415. for(i = overflow_start * track_map->channels ; 
  416. i < (samples + codec->work_overflow) * track_map->channels; 
  417. i++)
  418. {
  419. *input_ptr++ = codec->work_buffer[i];
  420. }
  421. codec->work_overflow = samples + codec->work_overflow - overflow_start;
  422. return result;
  423. }