summaryrefslogtreecommitdiff
path: root/apps/codecs/libwavpack/wputils.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libwavpack/wputils.c')
-rw-r--r--apps/codecs/libwavpack/wputils.c98
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
373void 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
483void WavpackAddWrapper (WavpackContext *wpc, void *data, ulong bcount) 470void 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
480int 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
500ulong 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; 496int 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) { 509ulong 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