# HG changeset patch # User Micha Lipski # Date 1204310936 21600 # Node ID b6f09d280f2cd6e385943e3145503da3a8d76571 # Parent 5ba6588580e045eb5e7a37c194b2e02879746ae2 Add support for 24-bit wavpack files. (Bugzilla #190) diff -r 5ba6588580e0 -r b6f09d280f2c src/wavpack/libwavpack.cxx --- a/src/wavpack/libwavpack.cxx Wed Feb 27 18:56:54 2008 +0900 +++ b/src/wavpack/libwavpack.cxx Fri Feb 29 12:48:56 2008 -0600 @@ -27,6 +27,8 @@ #endif #define BUFFER_SIZE 256 // read buffer size, in samples +#define SAMPLE_SIZE(a) (a == 8 ? sizeof(guint8) : (a == 16 ? sizeof(guint16) : sizeof(guint32))) +#define SAMPLE_FMT(a) (a == 8 ? FMT_S8 : (a == 16 ? FMT_S16_NE : (a == 24 ? FMT_S24_NE : FMT_S32_NE))) static void wv_load_config(); static int wv_is_our_fd(gchar *filename, VFSFile *file); @@ -152,10 +154,11 @@ { public: InputPlugin *mod; - int32_t *input; - int16_t *output; - int sample_rate; - int num_channels; + gint32 *input; + void *output; + gint sample_rate; + gint num_channels; + gint bits_per_sample; WavpackContext *ctx; char error_buff[4096]; // TODO: fixme! VFSFile *wv_Input, *wvc_Input; @@ -236,8 +239,9 @@ sample_rate = WavpackGetSampleRate(ctx); num_channels = WavpackGetNumChannels(ctx); - input = (int32_t *)calloc(BUFFER_SIZE, num_channels * sizeof(int32_t)); - output = (int16_t *)calloc(BUFFER_SIZE, num_channels * sizeof(int16_t)); + bits_per_sample = WavpackGetBitsPerSample(ctx); + input = (gint32 *) malloc(BUFFER_SIZE * num_channels * sizeof(guint32)); + output = malloc(BUFFER_SIZE * num_channels * SAMPLE_SIZE(bits_per_sample)); playback->set_params(playback, generate_title(playback->filename, ctx), (int) (WavpackGetNumSamples(ctx) / sample_rate) * 1000, (int) WavpackGetAverageBitrate(ctx, num_channels), @@ -247,18 +251,40 @@ bool open_audio() { - return mod->output->open_audio(FMT_S16_NE, sample_rate, num_channels); + return mod->output->open_audio(SAMPLE_FMT(bits_per_sample), sample_rate, num_channels); } void process_buffer(InputPlayback *playback, size_t num_samples) { - /* TODO: dithering */ - for (unsigned int i = 0; i < num_samples * num_channels; i++) - output[i] = input[i]; + gint i; + gint32* rp = input; + gint8* wp = reinterpret_cast(output); + gint16* wp2 = reinterpret_cast(output); + gint32* wp4 = reinterpret_cast(output); + + AUDDBG("Converting %d samples to %d bit\n", (gint)num_samples * num_channels, bits_per_sample); + + if (bits_per_sample % 8 != 0) { + AUDDBG("Can not convert to %d bps: not a multiple of 8\n", bits_per_sample); + } - playback->pass_audio(playback, FMT_S16_NE, + if (bits_per_sample == 8) { + for (i=0; ipass_audio(playback, SAMPLE_FMT(bits_per_sample), num_channels, - num_samples * num_channels * sizeof(int16_t), + num_samples * num_channels * SAMPLE_SIZE(bits_per_sample), output, NULL); }