diff options
Diffstat (limited to 'apps/codecs/libwavpack/wputils.c')
-rw-r--r-- | apps/codecs/libwavpack/wputils.c | 98 |
1 files changed, 46 insertions, 52 deletions
diff --git a/apps/codecs/libwavpack/wputils.c b/apps/codecs/libwavpack/wputils.c index 7f2ab14c44..479c18028f 100644 --- a/apps/codecs/libwavpack/wputils.c +++ b/apps/codecs/libwavpack/wputils.c | |||
@@ -365,17 +365,6 @@ WavpackContext *WavpackOpenFileOutput (void) | |||
365 | return &wpc; | 365 | return &wpc; |
366 | } | 366 | } |
367 | 367 | ||
368 | // Set the output buffer limits. This must be done before calling | ||
369 | // WavpackPackSamples(), but also may be done afterward to adjust | ||
370 | // the usable buffer. Note that writing CANNOT wrap in the buffer; the | ||
371 | // entire output block must fit in the buffer. | ||
372 | |||
373 | void WavpackSetOutputBuffer (WavpackContext *wpc, uchar *begin, uchar *end) | ||
374 | { | ||
375 | wpc->stream.blockbuff = begin; | ||
376 | wpc->stream.blockend = end; | ||
377 | } | ||
378 | |||
379 | // Set configuration for writing WavPack files. This must be done before | 368 | // Set configuration for writing WavPack files. This must be done before |
380 | // sending any actual samples, however it is okay to send wrapper or other | 369 | // sending any actual samples, however it is okay to send wrapper or other |
381 | // metadata before calling this. The "config" structure contains the following | 370 | // metadata before calling this. The "config" structure contains the following |
@@ -450,35 +439,33 @@ int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, ulong t | |||
450 | if (!(config->flags & CONFIG_JOINT_OVERRIDE) || (config->flags & CONFIG_JOINT_STEREO)) | 439 | if (!(config->flags & CONFIG_JOINT_OVERRIDE) || (config->flags & CONFIG_JOINT_STEREO)) |
451 | flags |= JOINT_STEREO; | 440 | flags |= JOINT_STEREO; |
452 | 441 | ||
442 | flags |= INITIAL_BLOCK | FINAL_BLOCK; | ||
443 | |||
444 | if (num_chans == 1) { | ||
445 | flags &= ~(JOINT_STEREO | CROSS_DECORR | HYBRID_BALANCE); | ||
446 | flags |= MONO_FLAG; | ||
447 | } | ||
448 | |||
449 | flags &= ~MAG_MASK; | ||
450 | flags += (1 << MAG_LSB) * ((flags & BYTES_STORED) * 8 + 7); | ||
451 | |||
453 | memcpy (wps->wphdr.ckID, "wvpk", 4); | 452 | memcpy (wps->wphdr.ckID, "wvpk", 4); |
454 | wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; | 453 | wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; |
455 | wps->wphdr.total_samples = wpc->total_samples; | 454 | wps->wphdr.total_samples = wpc->total_samples; |
456 | wps->wphdr.version = 0x403; | 455 | wps->wphdr.version = 0x403; |
457 | wps->wphdr.flags = flags; | 456 | wps->wphdr.flags = flags; |
458 | 457 | ||
459 | wps->wphdr.flags |= INITIAL_BLOCK; | ||
460 | wps->wphdr.flags |= FINAL_BLOCK; | ||
461 | |||
462 | if (num_chans == 1) { | ||
463 | wps->wphdr.flags &= ~(JOINT_STEREO | CROSS_DECORR | HYBRID_BALANCE); | ||
464 | wps->wphdr.flags |= MONO_FLAG; | ||
465 | } | ||
466 | |||
467 | pack_init (wpc); | 458 | pack_init (wpc); |
468 | return TRUE; | 459 | return TRUE; |
469 | } | 460 | } |
470 | 461 | ||
471 | // Add wrapper (currently RIFF only) to WavPack blocks. This should be called | 462 | // Add wrapper (currently RIFF only) to WavPack blocks. This should be called |
472 | // before sending any audio samples for the RIFF header or after all samples | 463 | // before sending any audio samples. If the exact contents of the RIFF header |
473 | // have been sent for any RIFF trailer. WavpackFlushSamples() should be called | 464 | // are not known because, for example, the file duration is uncertain or |
474 | // between sending the last samples and calling this for trailer data to make | 465 | // trailing chunks are possible, simply write a "dummy" header of the correct |
475 | // sure that headers and trailers don't get mixed up in very short files. If | 466 | // length. When all data has been written it will be possible to read the |
476 | // the exact contents of the RIFF header are not known because, for example, | 467 | // first block written and update the header directly. An example of this can |
477 | // the file duration is uncertain or trailing chunks are possible, simply write | 468 | // be found in the Audition filter. |
478 | // a "dummy" header of the correct length. When all data has been written it | ||
479 | // will be possible to read the first block written and update the header | ||
480 | // directly. An example of this can be found in the Audition filter. A | ||
481 | // return of FALSE indicates an error. | ||
482 | 469 | ||
483 | void WavpackAddWrapper (WavpackContext *wpc, void *data, ulong bcount) | 470 | void WavpackAddWrapper (WavpackContext *wpc, void *data, ulong bcount) |
484 | { | 471 | { |
@@ -486,38 +473,45 @@ void WavpackAddWrapper (WavpackContext *wpc, void *data, ulong bcount) | |||
486 | wpc->wrapper_bytes = bcount; | 473 | wpc->wrapper_bytes = bcount; |
487 | } | 474 | } |
488 | 475 | ||
476 | // Start a WavPack block to be stored in the specified buffer. This must be | ||
477 | // called before calling WavpackPackSamples(). Note that writing CANNOT wrap | ||
478 | // in the buffer; the entire output block must fit in the buffer. | ||
479 | |||
480 | int WavpackStartBlock (WavpackContext *wpc, uchar *begin, uchar *end) | ||
481 | { | ||
482 | wpc->stream.blockbuff = begin; | ||
483 | wpc->stream.blockend = end; | ||
484 | return pack_start_block (wpc); | ||
485 | } | ||
486 | |||
489 | // Pack the specified samples. Samples must be stored in longs in the native | 487 | // Pack the specified samples. Samples must be stored in longs in the native |
490 | // endian format of the executing processor. The number of samples specified | 488 | // endian format of the executing processor. The number of samples specified |
491 | // indicates composite samples (sometimes called "frames"). So, the actual | 489 | // indicates composite samples (sometimes called "frames"). So, the actual |
492 | // number of data points would be this "sample_count" times the number of | 490 | // number of data points would be this "sample_count" times the number of |
493 | // channels. Note that samples are accumulated here until enough exist to | 491 | // channels. The caller must decide how many samples to place in each |
494 | // create a complete WavPack block (or several blocks for multichannel audio). | 492 | // WavPack block (1/2 second is common), but this function may be called as |
495 | // If an application wants to break a block at a specific sample, then it must | 493 | // many times as desired to build the final block (and performs the actual |
496 | // simply call WavpackFlushSamples() to force an early termination. Completed | 494 | // compression during the call). A return of FALSE indicates an error. |
497 | // WavPack blocks are send to the function provided in the initial call to | ||
498 | // WavpackOpenFileOutput(). A return of FALSE indicates an error. | ||
499 | |||
500 | ulong WavpackPackSamples (WavpackContext *wpc, long *sample_buffer, ulong sample_count) | ||
501 | { | ||
502 | WavpackStream *wps = &wpc->stream; | ||
503 | ulong flags = wps->wphdr.flags; | ||
504 | ulong bcount; | ||
505 | int result; | ||
506 | 495 | ||
507 | flags &= ~MAG_MASK; | 496 | int WavpackPackSamples (WavpackContext *wpc, long *sample_buffer, ulong sample_count) |
508 | flags += (1 << MAG_LSB) * ((flags & BYTES_STORED) * 8 + 7); | 497 | { |
498 | if (!sample_count || pack_samples (wpc, sample_buffer, sample_count)) | ||
499 | return TRUE; | ||
509 | 500 | ||
510 | wps->wphdr.block_index = wps->sample_index; | 501 | strcpy_loc (wpc->error_message, "output buffer overflowed!"); |
511 | wps->wphdr.block_samples = sample_count; | 502 | return FALSE; |
512 | wps->wphdr.flags = flags; | 503 | } |
513 | 504 | ||
514 | result = pack_block (wpc, sample_buffer); | 505 | // Finish the WavPack block being built, returning the total size of the |
506 | // block in bytes. Note that the possible conversion of the WavPack header to | ||
507 | // little-endian takes place here. | ||
515 | 508 | ||
516 | if (!result) { | 509 | ulong WavpackFinishBlock (WavpackContext *wpc) |
517 | strcpy_loc (wpc->error_message, "output buffer overflowed!"); | 510 | { |
518 | return 0; | 511 | WavpackStream *wps = &wpc->stream; |
519 | } | 512 | ulong bcount; |
520 | 513 | ||
514 | pack_finish_block (wpc); | ||
521 | bcount = ((WavpackHeader *) wps->blockbuff)->ckSize + 8; | 515 | bcount = ((WavpackHeader *) wps->blockbuff)->ckSize + 8; |
522 | native_to_little_endian ((WavpackHeader *) wps->blockbuff, WavpackHeaderFormat); | 516 | native_to_little_endian ((WavpackHeader *) wps->blockbuff, WavpackHeaderFormat); |
523 | 517 | ||