Result SoundSourceWV::tryOpen(const AudioSourceConfig& audioSrcCfg) { DEBUG_ASSERT(!m_wpc); char msg[80]; // hold possible error message int openFlags = OPEN_WVC | OPEN_NORMALIZE; if ((kChannelCountMono == audioSrcCfg.channelCountHint) || (kChannelCountStereo == audioSrcCfg.channelCountHint)) { openFlags |= OPEN_2CH_MAX; } m_wpc = WavpackOpenFileInput( getLocalFileNameBytes().constData(), msg, openFlags, 0); if (!m_wpc) { qDebug() << "SSWV::open: failed to open file : " << msg; return ERR; } setChannelCount(WavpackGetReducedChannels(m_wpc)); setFrameRate(WavpackGetSampleRate(m_wpc)); setFrameCount(WavpackGetNumSamples(m_wpc)); if (WavpackGetMode(m_wpc) & MODE_FLOAT) { m_sampleScaleFactor = CSAMPLE_PEAK; } else { const int bitsPerSample = WavpackGetBitsPerSample(m_wpc); const uint32_t wavpackPeakSampleValue = uint32_t(1) << (bitsPerSample - 1); m_sampleScaleFactor = CSAMPLE_PEAK / CSAMPLE(wavpackPeakSampleValue); } return OK; }
SoundSource::OpenResult SoundSourceWV::tryOpen( OpenMode /*mode*/, const OpenParams& params) { DEBUG_ASSERT(!m_wpc); char msg[80]; // hold possible error message int openFlags = OPEN_WVC | OPEN_NORMALIZE; if ((params.channelCount() == 1) || (params.channelCount() == 2)) { openFlags |= OPEN_2CH_MAX; } // We use WavpackOpenFileInputEx to support Unicode paths on windows // http://www.wavpack.com/lib_use.txt QString wavPackFileName = getLocalFileName(); m_pWVFile = new QFile(wavPackFileName); m_pWVFile->open(QFile::ReadOnly); QString correctionFileName(wavPackFileName + "c"); if (QFile::exists(correctionFileName)) { // If there is a correction file, open it as well m_pWVCFile = new QFile(correctionFileName); m_pWVCFile->open(QFile::ReadOnly); } m_wpc = WavpackOpenFileInputEx(&s_streamReader, m_pWVFile, m_pWVCFile, msg, openFlags, 0); if (!m_wpc) { kLogger.warning() << "failed to open file : " << msg; return OpenResult::Failed; } setChannelCount(WavpackGetReducedChannels(m_wpc)); setSampleRate(WavpackGetSampleRate(m_wpc)); initFrameIndexRangeOnce( mixxx::IndexRange::forward( 0, WavpackGetNumSamples(m_wpc))); if (WavpackGetMode(m_wpc) & MODE_FLOAT) { m_sampleScaleFactor = CSAMPLE_PEAK; } else { const int bitsPerSample = WavpackGetBitsPerSample(m_wpc); if ((bitsPerSample >= 8) && (bitsPerSample <= 32)) { // Range of signed sample values: [-2 ^ (bitsPerSample - 1), 2 ^ (bitsPerSample - 1) - 1] const uint32_t absSamplePeak = 1u << (bitsPerSample - 1); DEBUG_ASSERT(absSamplePeak > 0); // Scaled range of sample values: [-CSAMPLE_PEAK, CSAMPLE_PEAK) m_sampleScaleFactor = CSAMPLE_PEAK / absSamplePeak; } else { kLogger.warning() << "Invalid bits per sample:" << bitsPerSample; return OpenResult::Aborted; } } m_curFrameIndex = frameIndexMin(); return OpenResult::Succeeded; }
static void wav_data_init (struct wavpack_data *data) { data->sample_num = WavpackGetNumSamples (data->wpc); data->sample_rate = WavpackGetSampleRate (data->wpc); data->channels = WavpackGetReducedChannels (data->wpc); data->duration = data->sample_num / data->sample_rate; data->mode = WavpackGetMode (data->wpc); data->avg_bitrate = WavpackGetAverageBitrate (data->wpc, 1) / 1000; data->ok = 1; debug ("File opened. S_n %d. S_r %d. Time %d. Avg_Bitrate %d.", data->sample_num, data->sample_rate, data->duration, data->avg_bitrate ); }
static int wavpack_assign_values(struct mpxplay_filehand_buffered_func_s *fbfs,void *fbds,struct wavpack_decoder_data *wpdi,struct mpxplay_infile_info_s *miis) { struct mpxplay_audio_decoder_info_s *adi=miis->audio_decoder_infos; unsigned int encmode; unsigned long pcmdatalen; adi->filechannels = adi->outchannels = WavpackGetReducedChannels(wpdi->wpc);//WavpackGetNumChannels(wpdi->wpc); if((adi->outchannels<PCM_MIN_CHANNELS) || (adi->outchannels>PCM_MAX_CHANNELS)) return 0; adi->bits = WavpackGetBitsPerSample(wpdi->wpc); if((adi->bits<PCM_MIN_BITS) || (adi->bits>PCM_MAX_BITS)) return 0; adi->freq = WavpackGetSampleRate(wpdi->wpc); wpdi->bytes_per_sample = WavpackGetBytesPerSample(wpdi->wpc); if(!adi->freq || !wpdi->bytes_per_sample) return 0; pcmdatalen=WavpackGetNumSamples(wpdi->wpc); miis->timemsec=(float)pcmdatalen*1000.0/adi->freq; encmode=WavpackGetMode(wpdi->wpc); if(encmode&MODE_FLOAT){ adi->infobits|=ADI_FLAG_FLOATOUT; adi->bits=1; wpdi->bytes_per_sample=sizeof(MPXPLAY_PCMOUT_FLOAT_T); } miis->longname="WavPack "; if(encmode&MODE_HYBRID){ adi->bitrate=(long)((float)miis->filesize*8.0/1000.0*(float)adi->freq/(float)pcmdatalen); }else{ long compr_ratio; adi->bitratetext=malloc(MPXPLAY_ADITEXTSIZE_BITRATE+8); if(!adi->bitratetext) return 0; compr_ratio=(long)(1000.0*(float)miis->filesize/(float)pcmdatalen/(float)wpdi->bytes_per_sample/(float)adi->filechannels); sprintf(adi->bitratetext,"%2d/%2.2d.%1.1d%%",adi->bits,compr_ratio/10,compr_ratio%10); } return 1; }
SoundSource::OpenResult SoundSourceWV::tryOpen(const AudioSourceConfig& audioSrcCfg) { DEBUG_ASSERT(!m_wpc); char msg[80]; // hold possible error message int openFlags = OPEN_WVC | OPEN_NORMALIZE; if ((kChannelCountMono == audioSrcCfg.getChannelCount()) || (kChannelCountStereo == audioSrcCfg.getChannelCount())) { openFlags |= OPEN_2CH_MAX; } // We use WavpackOpenFileInputEx to support Unicode paths on windows // http://www.wavpack.com/lib_use.txt QString wavPackFileName = getLocalFileName(); m_pWVFile = new QFile(wavPackFileName); m_pWVFile->open(QFile::ReadOnly); QString correctionFileName(wavPackFileName + "c"); if (QFile::exists(correctionFileName)) { // If there is a correction file, open it as well m_pWVCFile = new QFile(correctionFileName); m_pWVCFile->open(QFile::ReadOnly); } m_wpc = WavpackOpenFileInputEx(&s_streamReader, m_pWVFile, m_pWVCFile, msg, openFlags, 0); if (!m_wpc) { qDebug() << "SSWV::open: failed to open file : " << msg; return OpenResult::FAILED; } setChannelCount(WavpackGetReducedChannels(m_wpc)); setSamplingRate(WavpackGetSampleRate(m_wpc)); setFrameCount(WavpackGetNumSamples(m_wpc)); if (WavpackGetMode(m_wpc) & MODE_FLOAT) { m_sampleScaleFactor = CSAMPLE_PEAK; } else { const int bitsPerSample = WavpackGetBitsPerSample(m_wpc); const uint32_t wavpackPeakSampleValue = 1u << (bitsPerSample - 1); m_sampleScaleFactor = CSAMPLE_PEAK / wavpackPeakSampleValue; } return OpenResult::SUCCEEDED; }
bool AKSampler_Plugin::loadCompressedSampleFile(AKSampleFileDescriptor& sfd, float volBoostDb) { char errMsg[100]; WavpackContext* wpc = WavpackOpenFileInput(sfd.path, errMsg, OPEN_2CH_MAX, 0); if (wpc == 0) { printf("Wavpack error loading %s: %s\n", sfd.path, errMsg); return false; } AKSampleDataDescriptor sdd; sdd.sampleDescriptor = sfd.sampleDescriptor; sdd.sampleRate = (float)WavpackGetSampleRate(wpc); sdd.channelCount = WavpackGetReducedChannels(wpc); sdd.sampleCount = WavpackGetNumSamples(wpc); sdd.isInterleaved = sdd.channelCount > 1; sdd.data = new float[sdd.channelCount * sdd.sampleCount]; int mode = WavpackGetMode(wpc); WavpackUnpackSamples(wpc, (int32_t*)sdd.data, sdd.sampleCount); if ((mode & MODE_FLOAT) == 0) { // convert samples to floating-point int bps = WavpackGetBitsPerSample(wpc); float scale = 1.0f / (1 << (bps - 1)); float* pf = sdd.data; int32_t* pi = (int32_t*)pf; for (int i = 0; i < (sdd.sampleCount * sdd.channelCount); i++) *pf++ = scale * *pi++; } if (volBoostDb != 0.0f) { float scale = exp(volBoostDb / 20.0f); float* pf = sdd.data; for (int i = 0; i < (sdd.sampleCount * sdd.channelCount); i++) *pf++ *= scale; } loadSampleData(sdd); delete[] sdd.data; return true; }
/* this is called for each file to process */ enum codec_status codec_run(void) { WavpackContext *wpc; char error [80]; /* rockbox: comment 'set but unused' variables int bps; */ int nchans, sr_100; intptr_t param; if (codec_init()) return CODEC_ERROR; ci->seek_buffer (ci->id3->offset); /* Create a decoder instance */ wpc = WavpackOpenFileInput (read_callback, error); if (!wpc) return CODEC_ERROR; ci->configure(DSP_SWITCH_FREQUENCY, WavpackGetSampleRate (wpc)); codec_set_replaygain(ci->id3); /* bps = WavpackGetBytesPerSample (wpc); */ nchans = WavpackGetReducedChannels (wpc); ci->configure(DSP_SET_STEREO_MODE, nchans == 2 ? STEREO_INTERLEAVED : STEREO_MONO); sr_100 = ci->id3->frequency / 100; ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); /* The main decoder loop */ while (1) { int32_t nsamples; enum codec_command_action action = ci->get_command(¶m); if (action == CODEC_ACTION_HALT) break; if (action == CODEC_ACTION_SEEK_TIME) { int curpos_ms = WavpackGetSampleIndex (wpc) / sr_100 * 10; int n, d, skip; if (param > curpos_ms) { n = param - curpos_ms; d = ci->id3->length - curpos_ms; skip = (int)((int64_t)(ci->filesize - ci->curpos) * n / d); ci->seek_buffer (ci->curpos + skip); } else if (curpos_ms != 0) { n = curpos_ms - param; d = curpos_ms; skip = (int)((int64_t) ci->curpos * n / d); ci->seek_buffer (ci->curpos - skip); } wpc = WavpackOpenFileInput (read_callback, error); if (!wpc) { ci->seek_complete(); break; } ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); ci->seek_complete(); } nsamples = WavpackUnpackSamples (wpc, temp_buffer, BUFFER_SIZE / nchans); if (!nsamples) break; ci->pcmbuf_insert (temp_buffer, NULL, nsamples); ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); } return CODEC_OK; }
static int get_channels(void) { return WavpackGetReducedChannels(wpc); }
/* * This does the main decoding thing. * Requires an already opened WavpackContext. */ static void wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, struct replay_gain_info *replay_gain_info) { struct audio_format audio_format; format_samples_t format_samples; char chunk[CHUNK_SIZE]; int samples_requested, samples_got; float total_time, current_time; int bytes_per_sample, output_sample_size; int position; audio_format.sample_rate = WavpackGetSampleRate(wpc); audio_format.channels = WavpackGetReducedChannels(wpc); audio_format.bits = WavpackGetBitsPerSample(wpc); /* round bitwidth to 8-bit units */ audio_format.bits = (audio_format.bits + 7) & (~7); /* mpd handles max 24-bit samples */ if (audio_format.bits > 24) { audio_format.bits = 24; } if (!audio_format_valid(&audio_format)) { g_warning("Invalid audio format: %u:%u:%u\n", audio_format.sample_rate, audio_format.bits, audio_format.channels); return; } if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT) { format_samples = format_samples_float; } else { format_samples = format_samples_int; } total_time = WavpackGetNumSamples(wpc); total_time /= audio_format.sample_rate; bytes_per_sample = WavpackGetBytesPerSample(wpc); output_sample_size = audio_format_frame_size(&audio_format); /* wavpack gives us all kind of samples in a 32-bit space */ samples_requested = sizeof(chunk) / (4 * audio_format.channels); decoder_initialized(decoder, &audio_format, can_seek, total_time); position = 0; do { if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) { if (can_seek) { int where; where = decoder_seek_where(decoder); where *= audio_format.sample_rate; if (WavpackSeekSample(wpc, where)) { position = where; decoder_command_finished(decoder); } else { decoder_seek_error(decoder); } } else { decoder_seek_error(decoder); } } if (decoder_get_command(decoder) == DECODE_COMMAND_STOP) { break; } samples_got = WavpackUnpackSamples( wpc, (int32_t *)chunk, samples_requested ); if (samples_got > 0) { int bitrate = (int)(WavpackGetInstantBitrate(wpc) / 1000 + 0.5); position += samples_got; current_time = position; current_time /= audio_format.sample_rate; format_samples( bytes_per_sample, chunk, samples_got * audio_format.channels ); decoder_data( decoder, NULL, chunk, samples_got * output_sample_size, current_time, bitrate, replay_gain_info ); } } while (samples_got > 0); }
/* this is the codec entry point */ enum codec_status codec_main(void) { WavpackContext *wpc; char error [80]; int bps, nchans, sr_100; int retval; /* Generic codec initialisation */ ci->configure(DSP_SET_SAMPLE_DEPTH, 28); next_track: if (codec_init()) { retval = CODEC_ERROR; goto exit; } while (!*ci->taginfo_ready && !ci->stop_codec) ci->sleep(1); /* Create a decoder instance */ wpc = WavpackOpenFileInput (read_callback, error); if (!wpc) { retval = CODEC_ERROR; goto done; } ci->configure(DSP_SWITCH_FREQUENCY, WavpackGetSampleRate (wpc)); codec_set_replaygain(ci->id3); bps = WavpackGetBytesPerSample (wpc); nchans = WavpackGetReducedChannels (wpc); ci->configure(DSP_SET_STEREO_MODE, nchans == 2 ? STEREO_INTERLEAVED : STEREO_MONO); sr_100 = ci->id3->frequency / 100; ci->set_elapsed (0); /* The main decoder loop */ while (1) { int32_t nsamples; if (ci->seek_time && ci->taginfo_ready && ci->id3->length) { ci->seek_time--; int curpos_ms = WavpackGetSampleIndex (wpc) / sr_100 * 10; int n, d, skip; if (ci->seek_time > curpos_ms) { n = ci->seek_time - curpos_ms; d = ci->id3->length - curpos_ms; skip = (int)((int64_t)(ci->filesize - ci->curpos) * n / d); ci->seek_buffer (ci->curpos + skip); } else { n = curpos_ms - ci->seek_time; d = curpos_ms; skip = (int)((int64_t) ci->curpos * n / d); ci->seek_buffer (ci->curpos - skip); } wpc = WavpackOpenFileInput (read_callback, error); ci->seek_complete(); if (!wpc) break; ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); ci->yield (); } nsamples = WavpackUnpackSamples (wpc, temp_buffer, BUFFER_SIZE / nchans); if (!nsamples || ci->stop_codec || ci->new_track) break; ci->yield (); if (ci->stop_codec || ci->new_track) break; ci->pcmbuf_insert (temp_buffer, NULL, nsamples); ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); ci->yield (); } retval = CODEC_OK; done: if (ci->request_next_track()) goto next_track; exit: return retval; }