RtpAudioStream::RtpAudioStream(QObject *parent, _rtp_stream_info *rtp_stream) : QObject(parent), decoders_hash_(rtp_decoder_hash_table_new()), global_start_rel_time_(0.0), start_abs_offset_(0.0), start_rel_time_(0.0), stop_rel_time_(0.0), audio_out_rate_(0), audio_resampler_(0), audio_output_(0), max_sample_val_(1), color_(0), jitter_buffer_size_(50), timing_mode_(RtpAudioStream::JitterBuffer) { copy_address(&src_addr_, &rtp_stream->src_addr); src_port_ = rtp_stream->src_port; copy_address(&dst_addr_, &rtp_stream->dest_addr); dst_port_ = rtp_stream->dest_port; ssrc_ = rtp_stream->ssrc; // We keep visual samples in memory. Make fewer of them. visual_resampler_ = speex_resampler_init(1, default_audio_sample_rate_, visual_sample_rate_, SPEEX_RESAMPLER_QUALITY_MIN, NULL); speex_resampler_skip_zeros(visual_resampler_); QString tempname = QString("%1/wireshark_rtp_stream").arg(QDir::tempPath()); tempfile_ = new QTemporaryFile(tempname, this); tempfile_->open(); // RTP_STREAM_DEBUG("Writing to %s", tempname.toUtf8().constData()); }
AudioDecoderSpeex::AudioDecoderSpeex() : _speex_dec_state(speex_decoder_init(&speex_wb_mode)) { if (!_speex_dec_state) { throw MediaException(_("AudioDecoderSpeex: state initialization failed.")); } speex_bits_init(&_speex_bits); speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_framesize); #ifdef RESAMPLING_SPEEX int err = 0; _resampler = speex_resampler_init(1, 16000, 44100, SPEEX_RESAMPLER_QUALITY_DEFAULT, &err); if (err != RESAMPLER_ERR_SUCCESS) { throw MediaException(_("AudioDecoderSpeex: initialization failed.")); } spx_uint32_t num = 0, den = 0; speex_resampler_get_ratio (_resampler, &num, &den); assert(num && den); boost::rational<boost::uint32_t> numsamples(den, num); numsamples *= _speex_framesize * 2 /* convert to stereo */; _target_frame_size = boost::rational_cast<boost::uint32_t>(numsamples); #endif }
AudioOutputSample::AudioOutputSample(const QString &name, SoundFile *psndfile, bool loop, unsigned int freq) : AudioOutputUser(name) { int err; sfHandle = psndfile; iOutSampleRate = freq; // Check if the file is good if (sfHandle->channels() <= 0 || sfHandle->channels() > 2) { sfHandle = NULL; return; } /* qWarning() << "Channels: " << sfHandle->channels(); qWarning() << "Samplerate: " << sfHandle->samplerate(); qWarning() << "Target Sr.: " << freq; qWarning() << "Format: " << sfHandle->format() << endl; */ // If the frequencies don't match initialize the resampler if (sfHandle->samplerate() != static_cast<int>(freq)) { srs = speex_resampler_init(1, sfHandle->samplerate(), iOutSampleRate, 3, &err); if (err != RESAMPLER_ERR_SUCCESS) { qWarning() << "Initialize " << sfHandle->samplerate() << " to " << iOutSampleRate << " resampler failed!"; srs = NULL; sfHandle = NULL; return; } } else { srs = NULL; } iLastConsume = iBufferFilled = 0; bLoop = loop; bEof = false; }
int create_resampler(uint32_t inSampleRate, uint32_t outSampleRate, uint32_t channelCount, uint32_t quality, struct resampler_buffer_provider* provider, struct resampler_itfe **resampler) { int error; struct resampler *rsmp; ALOGV("create_resampler() In SR %d Out SR %d channels %d", inSampleRate, outSampleRate, channelCount); if (resampler == NULL) { return -EINVAL; } *resampler = NULL; if (quality <= RESAMPLER_QUALITY_MIN || quality >= RESAMPLER_QUALITY_MAX) { return -EINVAL; } rsmp = (struct resampler *)calloc(1, sizeof(struct resampler)); rsmp->speex_resampler = speex_resampler_init(channelCount, inSampleRate, outSampleRate, quality, &error); if (rsmp->speex_resampler == NULL) { ALOGW("ReSampler: Cannot create speex resampler: %s", speex_resampler_strerror(error)); free(rsmp); return -ENODEV; } rsmp->itfe.reset = resampler_reset; rsmp->itfe.resample_from_provider = resampler_resample_from_provider; rsmp->itfe.resample_from_input = resampler_resample_from_input; rsmp->itfe.delay_ns = resampler_delay_ns; rsmp->provider = provider; rsmp->in_sample_rate = inSampleRate; rsmp->out_sample_rate = outSampleRate; rsmp->channel_count = channelCount; rsmp->in_buf = NULL; rsmp->in_buf_size = 0; resampler_reset(&rsmp->itfe); int frames = speex_resampler_get_input_latency(rsmp->speex_resampler); rsmp->speex_delay_ns = (int32_t)((1000000000 * (int64_t)frames) / rsmp->in_sample_rate); frames = speex_resampler_get_output_latency(rsmp->speex_resampler); rsmp->speex_delay_ns += (int32_t)((1000000000 * (int64_t)frames) / rsmp->out_sample_rate); *resampler = &rsmp->itfe; ALOGV("create_resampler() DONE rsmp %p &rsmp->itfe %p speex %p", rsmp, &rsmp->itfe, rsmp->speex_resampler); return 0; }
void Resampler::initialize() { if(dstSamplesPerSec_ == srcSamplesPerSec_){ convertTypeFunc_ = getConvTypeFunc( dstNumChannels_, dstBytesPerSample_, srcNumChannels_, srcBytesPerSample_); }else{ if(resamplerChannels_ != srcNumChannels_){ destroyResampler(); } if(NULL == resampler_){ resampler_ = speex_resampler_init(srcNumChannels_, srcSamplesPerSec_, dstSamplesPerSec_, SPEEX_RESAMPLER_QUALITY_DEFAULT, NULL); }else{ speex_resampler_set_rate(resampler_, srcSamplesPerSec_, dstSamplesPerSec_); speex_resampler_reset_mem(resampler_); } resampleRate_ = static_cast<f32>(dstSamplesPerSec_)/srcSamplesPerSec_; convertTypeFunc_ = getConvTypeFunc( dstNumChannels_, dstBytesPerSample_, srcNumChannels_, dstBytesPerSample_); } }
cubeb_resampler * cubeb_resampler_create(cubeb_stream * stream, cubeb_stream_params params, unsigned int out_rate, cubeb_data_callback callback, long buffer_frame_count, void * user_ptr, cubeb_resampler_quality quality) { if (params.rate != out_rate) { SpeexResamplerState * resampler = NULL; resampler = speex_resampler_init(params.channels, params.rate, out_rate, to_speex_quality(quality), NULL); if (!resampler) { return NULL; } return new cubeb_resampler_speex(resampler, stream, params, out_rate, callback, buffer_frame_count, user_ptr); } return new noop_resampler(stream, callback, user_ptr); }
void AudioInput::initializeMixer() { int err; if (srsMic) speex_resampler_destroy(srsMic); if (srsEcho) speex_resampler_destroy(srsEcho); if (pfMicInput) delete [] pfMicInput; if (pfEchoInput) delete [] pfEchoInput; if (pfOutput) delete [] pfOutput; if (iMicFreq != iSampleRate) srsMic = speex_resampler_init(1, iMicFreq, iSampleRate, 3, &err); iMicLength = (iFrameSize * iMicFreq) / iSampleRate; pfMicInput = new float[iMicLength]; pfOutput = new float[iFrameSize * max(1U,iEchoChannels)]; if (iEchoChannels > 0) { bEchoMulti = g_struct.s.bEchoMulti; if (iEchoFreq != iSampleRate) srsEcho = speex_resampler_init(bEchoMulti ? iEchoChannels : 1, iEchoFreq, iSampleRate, 3, &err); iEchoLength = (iFrameSize * iEchoFreq) / iSampleRate; iEchoMCLength = bEchoMulti ? iEchoLength * iEchoChannels : iEchoLength; iEchoFrameSize = bEchoMulti ? iFrameSize * iEchoChannels : iFrameSize; pfEchoInput = new float[iEchoMCLength]; } else { srsEcho = NULL; pfEchoInput = NULL; } imfMic = chooseMixer(iMicChannels, eMicFormat); imfEcho = chooseMixer(iEchoChannels, eEchoFormat); iMicSampleSize = static_cast<int>(iMicChannels * ((eMicFormat == SampleFloat) ? sizeof(float) : sizeof(short))); iEchoSampleSize = static_cast<int>(iEchoChannels * ((eEchoFormat == SampleFloat) ? sizeof(float) : sizeof(short))); bResetProcessor = true; Trace("AudioInput: Initialized mixer for %d channel %d hz mic and %d channel %d hz echo", iMicChannels, iMicFreq, iEchoChannels, iEchoFreq); }
rl_resampler_t* rl_resampler_create( unsigned in_freq ) { if ( in_freq != RL_SAMPLE_RATE ) { return (rl_resampler_t*)speex_resampler_init( 2, in_freq, RL_SAMPLE_RATE, RL_RESAMPLER_QUALITY, NULL ); } return (rl_resampler_t*)&passthrough; }
static void resample_process_ms2(MSFilter *obj) { ResampleData *dt=(ResampleData*)obj->data; mblk_t *m; if (dt->output_rate==dt->input_rate) { while((m=ms_queue_get(obj->inputs[0]))!=NULL) { ms_queue_put(obj->outputs[0],m); } return; } ms_filter_lock(obj); if (dt->handle!=NULL) { unsigned int inrate=0, outrate=0; speex_resampler_get_rate(dt->handle,&inrate,&outrate); if (inrate!=dt->input_rate || outrate!=dt->output_rate) { speex_resampler_destroy(dt->handle); dt->handle=0; } } if (dt->handle==NULL) { int err=0; dt->handle=speex_resampler_init(dt->nchannels, dt->input_rate, dt->output_rate, SPEEX_RESAMPLER_QUALITY_VOIP, &err); } while((m=ms_queue_get(obj->inputs[0]))!=NULL) { unsigned int inlen=(m->b_wptr-m->b_rptr)/(2*dt->nchannels); unsigned int outlen=((inlen*dt->output_rate)/dt->input_rate)+1; unsigned int inlen_orig=inlen; mblk_t *om=allocb(outlen*2*dt->nchannels,0); if (dt->nchannels==1) { speex_resampler_process_int(dt->handle, 0, (int16_t*)m->b_rptr, &inlen, (int16_t*)om->b_wptr, &outlen); } else { speex_resampler_process_interleaved_int(dt->handle, (int16_t*)m->b_rptr, &inlen, (int16_t*)om->b_wptr, &outlen); } if (inlen_orig!=inlen) { ms_error("Bug in resampler ! only %u samples consumed instead of %u, out=%u", inlen,inlen_orig,outlen); } om->b_wptr+=outlen*2*dt->nchannels; mblk_set_timestamp_info(om,dt->ts); dt->ts+=outlen; ms_queue_put(obj->outputs[0],om); freemsg(m); } ms_filter_unlock(obj); }
static int resamp_new(struct ast_trans_pvt *pvt) { int err; if (!(pvt->pvt = speex_resampler_init(1, ast_format_rate(&pvt->t->src_format), ast_format_rate(&pvt->t->dst_format), 5, &err))) { return -1; } return 0; }
nsresult OpusTrackEncoder::Init(int aChannels, int aSamplingRate) { // This monitor is used to wake up other methods that are waiting for encoder // to be completely initialized. ReentrantMonitorAutoEnter mon(mReentrantMonitor); NS_ENSURE_TRUE((aChannels <= MAX_SUPPORTED_AUDIO_CHANNELS) && (aChannels > 0), NS_ERROR_FAILURE); // This version of encoder API only support 1 or 2 channels, // So set the mChannels less or equal 2 and // let InterleaveTrackData downmix pcm data. mChannels = aChannels > MAX_CHANNELS ? MAX_CHANNELS : aChannels; // Reject non-audio sample rates. NS_ENSURE_TRUE(aSamplingRate >= 8000, NS_ERROR_INVALID_ARG); NS_ENSURE_TRUE(aSamplingRate <= 192000, NS_ERROR_INVALID_ARG); // According to www.opus-codec.org, creating an opus encoder requires the // sampling rate of source signal be one of 8000, 12000, 16000, 24000, or // 48000. If this constraint is not satisfied, we resample the input to 48kHz. nsTArray<int> supportedSamplingRates; supportedSamplingRates.AppendElements(kOpusSupportedInputSamplingRates, ArrayLength(kOpusSupportedInputSamplingRates)); if (!supportedSamplingRates.Contains(aSamplingRate)) { int error; mResampler = speex_resampler_init(mChannels, aSamplingRate, kOpusSamplingRate, SPEEX_RESAMPLER_QUALITY_DEFAULT, &error); if (error != RESAMPLER_ERR_SUCCESS) { return NS_ERROR_FAILURE; } } mSamplingRate = aSamplingRate; NS_ENSURE_TRUE(mSamplingRate > 0, NS_ERROR_FAILURE); int error = 0; mEncoder = opus_encoder_create(GetOutputSampleRate(), mChannels, OPUS_APPLICATION_AUDIO, &error); mInitialized = (error == OPUS_OK); if (mAudioBitrate) { opus_encoder_ctl(mEncoder, OPUS_SET_BITRATE(static_cast<int>(mAudioBitrate))); } mReentrantMonitor.NotifyAll(); return error == OPUS_OK ? NS_OK : NS_ERROR_FAILURE; }
void AudioInput::initializeMixer() { int err; if (srsMic) speex_resampler_destroy(srsMic); if (srsEcho) speex_resampler_destroy(srsEcho); if (pfMicInput) delete [] pfMicInput; if (pfEchoInput) delete [] pfEchoInput; if (pfOutput) delete [] pfOutput; if (iMicFreq != SAMPLE_RATE) srsMic = speex_resampler_init(1, iMicFreq, SAMPLE_RATE, 3, &err); iMicLength = (iFrameSize * iMicFreq) / SAMPLE_RATE; pfMicInput = new float[iMicLength]; pfOutput = new float[iFrameSize]; if (iEchoChannels > 0) { if (iEchoFreq != SAMPLE_RATE) srsEcho = speex_resampler_init(1, iEchoFreq, SAMPLE_RATE, 3, &err); iEchoLength = (iFrameSize * iEchoFreq) / SAMPLE_RATE; pfEchoInput = new float[iEchoLength]; } else { srsEcho = NULL; pfEchoInput = NULL; } imfMic = chooseMixer(iMicChannels, eMicFormat); imfEcho = chooseMixer(iEchoChannels, eEchoFormat); iMicSampleSize = iMicChannels * ((eMicFormat == SampleFloat) ? sizeof(float) : sizeof(short)); iEchoSampleSize = iEchoChannels * ((eEchoFormat == SampleFloat) ? sizeof(float) : sizeof(short)); bResetProcessor = true; qWarning("AudioInput: Initialized mixer for %d channel %d hz mic and %d channel %d hz echo", iMicChannels, iMicFreq, iEchoChannels, iEchoFreq); }
int Aulib::AudioResamplerSpeex::adjustForOutputSpec(unsigned dstRate, unsigned srcRate, unsigned channels) { int err; d->fResampler.reset(speex_resampler_init(channels, srcRate, dstRate, 10, &err)); if (err) { d->fResampler = nullptr; return -1; } return 0; }
static int resamp_new(struct ast_trans_pvt *pvt) { int err; if (!(pvt->pvt = speex_resampler_init(1, pvt->t->src_codec.sample_rate, pvt->t->dst_codec.sample_rate, 5, &err))) { return -1; } ast_assert(pvt->f.subclass.format == NULL); pvt->f.subclass.format = ao2_bump(ast_format_cache_get_slin_by_rate(pvt->t->dst_codec.sample_rate)); return 0; }
static void resample_init_speex(ResampleData *dt){ int err=0; int quality=SPEEX_RESAMPLER_QUALITY_VOIP; /*default value is voip*/ #if defined(__arm__) || defined(_M_ARM) /*on ARM, NEON optimization are mandatory to support this quality, else using basic mode*/ #if SPEEX_LIB_SET_CPU_FEATURES if (dt->cpuFeatures != SPEEX_LIB_CPU_FEATURE_NEON) quality=SPEEX_RESAMPLER_QUALITY_MIN; #elif !defined(__ARM_NEON__) quality=SPEEX_RESAMPLER_QUALITY_MIN; #endif /*SPEEX_LIB_SET_CPU_FEATURES*/ #endif /*defined(__arm__) || defined(_M_ARM)*/ ms_message("Initializing speex resampler in mode [%s] ",(quality==SPEEX_RESAMPLER_QUALITY_VOIP?"voip":"min")); dt->handle=speex_resampler_init(dt->in_nchannels, dt->input_rate, dt->output_rate, quality, &err); }
static int ebur128_init_resampler(ebur128_state* st) { int errcode = EBUR128_SUCCESS; if (st->samplerate < 96000) { st->d->oversample_factor = 4; } else if (st->samplerate < 192000) { st->d->oversample_factor = 2; } else { st->d->oversample_factor = 1; st->d->resampler_buffer_input = NULL; st->d->resampler_buffer_output = NULL; st->d->resampler = NULL; } st->d->resampler_buffer_input_frames = st->d->samples_in_100ms * 4; st->d->resampler_buffer_input = malloc(st->d->resampler_buffer_input_frames * st->channels * sizeof(float)); CHECK_ERROR(!st->d->resampler_buffer_input, EBUR128_ERROR_NOMEM, exit) st->d->resampler_buffer_output_frames = st->d->resampler_buffer_input_frames * st->d->oversample_factor; st->d->resampler_buffer_output = malloc (st->d->resampler_buffer_output_frames * st->channels * sizeof(float)); CHECK_ERROR(!st->d->resampler_buffer_output, EBUR128_ERROR_NOMEM, free_input) st->d->resampler = speex_resampler_init ((spx_uint32_t) st->channels, (spx_uint32_t) st->samplerate, (spx_uint32_t) (st->samplerate * st->d->oversample_factor), 8, NULL); CHECK_ERROR(!st->d->resampler, EBUR128_ERROR_NOMEM, free_output) return errcode; free_output: free(st->d->resampler_buffer_output); st->d->resampler_buffer_output = NULL; free_input: free(st->d->resampler_buffer_input); st->d->resampler_buffer_input = NULL; exit: return errcode; }
int CMAlsaAudioSink::init() { int err; if ((err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, m_channels, m_rate, 1, 100000)) < 0) { qDebug() << "Set params error: " << snd_strerror(err); return false; } #if 0 if (m_resampler) speex_resampler_destroy(m_resampler); m_resampler=speex_resampler_init(m_channels, m_rate, m_srate, 10, &err); #endif return true; }
size_t AudioNodeExternalInputStream::GetTrackMapEntry(const StreamBuffer::Track& aTrack, GraphTime aFrom) { AudioSegment* segment = aTrack.Get<AudioSegment>(); // Check the map for an existing entry corresponding to the input track. for (size_t i = 0; i < mTrackMap.Length(); ++i) { TrackMapEntry* map = &mTrackMap[i]; if (map->mTrackID == aTrack.GetID()) { return i; } } // Determine channel count by finding the first entry with non-silent data. AudioSegment::ChunkIterator ci(*segment); while (!ci.IsEnded() && ci->IsNull()) { ci.Next(); } if (ci.IsEnded()) { // The track is entirely silence so far, we can ignore it for now. return nsTArray<TrackMapEntry>::NoIndex; } // Create a speex resampler with the same sample rate and number of channels // as the track. SpeexResamplerState* resampler = nullptr; size_t channelCount = std::min((*ci).mChannelData.Length(), WebAudioUtils::MaxChannelCount); if (aTrack.GetRate() != mSampleRate) { resampler = speex_resampler_init(channelCount, aTrack.GetRate(), mSampleRate, SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr); speex_resampler_skip_zeros(resampler); } TrackMapEntry* map = mTrackMap.AppendElement(); map->mEndOfConsumedInputTicks = 0; map->mEndOfLastInputIntervalInInputStream = -1; map->mEndOfLastInputIntervalInOutputStream = -1; map->mSamplesPassedToResampler = TimeToTicksRoundUp(aTrack.GetRate(), GraphTimeToStreamTime(aFrom)); map->mResampler = resampler; map->mResamplerChannelCount = channelCount; map->mTrackID = aTrack.GetID(); return mTrackMap.Length() - 1; }
bool ResamplePCM(uint32 NumChannels, const TArray<uint8>& InBuffer, uint32 InSampleRate, TArray<uint8>& OutBuffer, uint32 OutSampleRate) const { // Initialize resampler to convert to desired rate for Opus int32 err = 0; SpeexResamplerState* resampler = speex_resampler_init(NumChannels, InSampleRate, OutSampleRate, SPEEX_RESAMPLER_QUALITY_DESKTOP, &err); if (err != RESAMPLER_ERR_SUCCESS) { speex_resampler_destroy(resampler); return false; } // Calculate extra space required for sample rate const uint32 SampleStride = SAMPLE_SIZE * NumChannels; const float Duration = (float)InBuffer.Num() / (InSampleRate * SampleStride); const int32 SafeCopySize = (Duration + 1) * OutSampleRate * SampleStride; OutBuffer.Empty(SafeCopySize); OutBuffer.AddUninitialized(SafeCopySize); uint32 InSamples = InBuffer.Num() / SampleStride; uint32 OutSamples = OutBuffer.Num() / SampleStride; // Do resampling and check results if (NumChannels == 1) { err = speex_resampler_process_int(resampler, 0, (const short*)(InBuffer.GetData()), &InSamples, (short*)(OutBuffer.GetData()), &OutSamples); } else { err = speex_resampler_process_interleaved_int(resampler, (const short*)(InBuffer.GetData()), &InSamples, (short*)(OutBuffer.GetData()), &OutSamples); } speex_resampler_destroy(resampler); if (err != RESAMPLER_ERR_SUCCESS) { return false; } // reduce the size of Out Buffer if more space than necessary was allocated const int32 WrittenBytes = (int32)(OutSamples * SampleStride); if (WrittenBytes < OutBuffer.Num()) { OutBuffer.SetNum(WrittenBytes, true); } return true; }
PJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool, pj_bool_t high_quality, pj_bool_t large_filter, unsigned channel_count, unsigned rate_in, unsigned rate_out, unsigned samples_per_frame, pjmedia_resample **p_resample) { pjmedia_resample *resample; int quality; int err; PJ_ASSERT_RETURN(pool && p_resample && rate_in && rate_out && samples_per_frame, PJ_EINVAL); resample = PJ_POOL_ZALLOC_T(pool, pjmedia_resample); PJ_ASSERT_RETURN(resample, PJ_ENOMEM); if (high_quality) { if (large_filter) quality = 10; else quality = 7; } else { quality = 3; } resample->in_samples_per_frame = samples_per_frame; resample->out_samples_per_frame = rate_out / (rate_in / samples_per_frame); resample->state = speex_resampler_init(channel_count, rate_in, rate_out, quality, &err); if (resample->state == NULL || err != RESAMPLER_ERR_SUCCESS) return PJ_ENOMEM; *p_resample = resample; PJ_LOG(5,(THIS_FILE, "resample created: quality=%d, ch=%d, in/out rate=%d/%d", quality, channel_count, rate_in, rate_out)); return PJ_SUCCESS; }
static int Open (vlc_object_t *obj) { filter_t *filter = (filter_t *)obj; /* Will change rate */ if (filter->fmt_in.audio.i_rate == filter->fmt_out.audio.i_rate /* Cannot convert format */ || filter->fmt_in.audio.i_format != filter->fmt_out.audio.i_format /* Cannot remix */ || filter->fmt_in.audio.i_physical_channels != filter->fmt_out.audio.i_physical_channels || filter->fmt_in.audio.i_original_channels != filter->fmt_out.audio.i_original_channels) return VLC_EGENERIC; switch (filter->fmt_in.audio.i_format) { case VLC_CODEC_FL32: break; case VLC_CODEC_S16N: break; default: return VLC_EGENERIC; } SpeexResamplerState *st; unsigned channels = aout_FormatNbChannels (&filter->fmt_in.audio); unsigned q = var_InheritInteger (obj, "speex-resampler-quality"); if (unlikely(q > 10)) q = 3; int err; st = speex_resampler_init(channels, filter->fmt_in.audio.i_rate, filter->fmt_out.audio.i_rate, q, &err); if (unlikely(st == NULL)) { msg_Err (obj, "cannot initialize resampler: %s", speex_resampler_strerror (err)); return VLC_ENOMEM; } filter->p_sys = (filter_sys_t *)st; filter->pf_audio_filter = Resample; return VLC_SUCCESS; }
/* * make speexdsp resampler. * @param channel_num target channel num * @param input_sample_rate input sample rate * @param output_sample_rate output sample rate * @param quality quality for speexdsp resampler. 0:low quality - 10:max quality. * @return resampler object. */ ttLibC_SpeexdspResampler *ttLibC_SpeexdspResampler_make(uint32_t channel_num, uint32_t input_sample_rate, uint32_t output_sample_rate, uint32_t quality) { ttLibC_SpeexdspResampler_ *resampler = (ttLibC_SpeexdspResampler_ *)ttLibC_malloc(sizeof(ttLibC_SpeexdspResampler_)); if(resampler == NULL) { ERR_PRINT("failed to allocate resampler object."); return NULL; } int error_num; resampler->resampler = speex_resampler_init(channel_num, input_sample_rate, output_sample_rate, quality, &error_num); if(error_num != 0 || resampler->resampler == NULL) { ERR_PRINT("failed to init speex resampler."); ttLibC_free(resampler); return NULL; } resampler->inherit_super.channel_num = channel_num; resampler->inherit_super.input_sample_rate = input_sample_rate; resampler->inherit_super.output_sample_rate = output_sample_rate; resampler->inherit_super.quality = quality; return (ttLibC_SpeexdspResampler *)resampler; }
//============================================================================== std::vector<float> AudioAnalysisManager::resamplePlot(std::vector<float> v) { std::vector<float> resampledSignal; resampledSignal.resize(512); float *inF; inF = new float[v.size()]; float *outF; outF = new float[v.size()]; for (int i = 0;i < v.size();i++) { inF[i] = (float) v[i]; } SpeexResamplerState *resampler; int err = 0; resampler = speex_resampler_init(1, (spx_uint32_t) v.size(), 512, 0, &err); spx_uint32_t inLen = (spx_uint32_t) v.size(); spx_uint32_t outLen = (spx_uint32_t) 512; err = speex_resampler_process_float(resampler, 0, inF, &inLen, outF, &outLen); for (int i = 0;i < resampledSignal.size();i++) { resampledSignal[i] = outF[i]; } delete [] inF; delete [] outF; speex_resampler_destroy(resampler); return resampledSignal; }
bool AudioResampler::Open(FILE* file) { if (wrapped_decoder->Open(file)) { wrapped_decoder->GetFormat(input_rate, input_format, nr_of_channels); //determine if the input format is supported by the resampler switch (input_format) { case Format::F32: output_format = input_format; break; #ifdef HAVE_LIBSPEEXDSP case Format::S16: output_format = input_format; break; #endif default: output_format = Format::F32; break; } //Set input format to output_format if possible wrapped_decoder->SetFormat(input_rate, output_format, nr_of_channels); //Reread format to get new values wrapped_decoder->GetFormat(input_rate, input_format, nr_of_channels); output_rate = input_rate; #if defined(HAVE_LIBSPEEXDSP) conversion_state = speex_resampler_init(nr_of_channels, input_rate, output_rate, sampling_quality, &lasterror); conversion_data.ratio_num = input_rate; conversion_data.ratio_denom = output_rate; speex_resampler_skip_zeros(conversion_state); #elif defined(HAVE_LIBSAMPLERATE) conversion_state = src_new(sampling_quality, nr_of_channels, &lasterror); #endif //Init the conversion data structure conversion_data.input_frames = 0; conversion_data.input_frames_used = 0; finished = false; if (conversion_state) return true; } conversion_state = nullptr; return false; }
bool COggVorbisFileHelper::init( std::string fin_str,bool bResample /*= true*/,int nResQuality/*=0*/, char* pData /*= NULL*/, uint32 iSize /*= 0*/) { cleanup(); #if defined(HAVE_PTHREAD) pthread_mutex_lock(&mutex1); #endif nSoundChannel = s3eSoundGetFreeChannel(); if(nSoundChannel == -1) { m_strLastError.clear(); m_strLastError = "Cannot open a sound channel."; s3eDebugTracePrintf("%s\n",m_strLastError.c_str()); cleanup(); #if defined(HAVE_PTHREAD) pthread_mutex_unlock(&mutex1); #endif return false; } s3eSoundChannelRegister(nSoundChannel, S3E_CHANNEL_GEN_AUDIO, GenerateAudioCallback, this); s3eSoundChannelRegister(nSoundChannel, S3E_CHANNEL_END_SAMPLE, EndSampleCallback, this); ov_callbacks callbacks; callbacks.read_func = read_func; callbacks.seek_func = seek_func; callbacks.close_func = close_func; callbacks.tell_func = tell_func; if (pData != NULL) { oggvorbis_filein = s3eFileOpenFromMemory(pData, iSize); } else { if(false /*oggvorbis_filein != NULL*/) { if(s3eFileClose(oggvorbis_filein) == S3E_RESULT_ERROR) { m_strLastError.clear(); m_strLastError = "Cannot close old file"; s3eDebugTracePrintf("%s\n",m_strLastError.c_str()); cleanup(); #if defined(HAVE_PTHREAD) pthread_mutex_unlock(&mutex1); #endif return false; } } oggvorbis_filein = s3eFileOpen(fin_str.c_str(),"rb"); } if(oggvorbis_filein == NULL) { m_strLastError.clear(); m_strLastError = "Cannot open file " + fin_str; s3eDebugTracePrintf("%s\n",m_strLastError.c_str()); cleanup(); #if defined(HAVE_PTHREAD) pthread_mutex_unlock(&mutex1); #endif return false; } if(ov_open_callbacks(oggvorbis_filein, &vf, NULL, 0, callbacks) < 0) { m_strLastError.clear(); m_strLastError = "Input does not appear to be an Ogg bitstream."; s3eDebugTracePrintf("%s\n",m_strLastError.c_str()); cleanup(); #if defined(HAVE_PTHREAD) pthread_mutex_unlock(&mutex1); #endif return false; } /* Throw the comments plus a few lines about the bitstream we're decoding */ { char **ptr=ov_comment(&vf,-1)->user_comments; vorbis_info *vi=ov_info(&vf,-1); //while(*ptr) //{ // fprintf(stderr,"%s\n",*ptr); // ++ptr; //} total_samples = ov_pcm_total(&vf,-1); time_length = ov_time_total_func(&vf,-1); nChannels = vi->channels; nRate = vi->rate; s3eSoundChannelSetInt(nSoundChannel, S3E_CHANNEL_RATE, nRate); nOutputRate = s3eSoundGetInt(S3E_SOUND_OUTPUT_FREQ); int gcd = GCD(nRate, nOutputRate); nW = nRate / gcd; nL = nOutputRate / gcd; dResampleFactor = (float)nOutputRate / (float)vi->rate; // 0 - 4.0 ? int err; bEnableResampling = bResample; nResampleQuality = nResQuality; if(bEnableResampling) { if(res_contL) speex_resampler_destroy(res_contL); res_contL = speex_resampler_init(1,nRate,nOutputRate,nResampleQuality,&err); if(res_contR) speex_resampler_destroy(res_contR); res_contR = speex_resampler_init(1,nRate,nOutputRate,nResampleQuality,&err); if(err != RESAMPLER_ERR_SUCCESS) { m_strLastError.clear(); m_strLastError = "Cannot start resampler."; s3eDebugTracePrintf("%s\n",m_strLastError.c_str()); cleanup(); #if defined(HAVE_PTHREAD) pthread_mutex_unlock(&mutex1); #endif return false; } } else { int fs = min(nRate, nOutputRate); double fc = (fs/2) / (double)nOutputRate; // half the input sample rate (eg nyquist limit of input) // Generate filter coefficients wsfirLP(dFilterCoefficients, nFilterCoefficients, W_BLACKMAN, fc); if(dResampleFactor != 1) s3eDebugErrorShow(S3E_MESSAGE_CONTINUE,"Resample factor not 1 but resampling disabled"); } s3eDebugTracePrintf("\nBitstream is %d channel, %ldHz\n",vi->channels,vi->rate); s3eDebugTracePrintf("\nDecoded length: %ld samples\n",(long)total_samples); s3eDebugTracePrintf("Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor); s3eDebugTracePrintf("Resampling by rational factor %d / %d", nW, nL); } bStopDecoding = false; nStatus = OH_READY; #if defined(HAVE_PTHREAD) pthread_mutex_unlock(&mutex1); #endif return true; }
void MediaDecodeTask::Decode() { MOZ_ASSERT(!mThreadPool == NS_IsMainThread(), "We should be on the main thread only if we don't have a thread pool"); mBufferDecoder->BeginDecoding(NS_GetCurrentThread()); // Tell the decoder reader that we are not going to play the data directly, // and that we should not reject files with more channels than the audio // bakend support. mDecoderReader->SetIgnoreAudioOutputFormat(); mDecoderReader->OnDecodeThreadStart(); MediaInfo mediaInfo; nsAutoPtr<MetadataTags> tags; nsresult rv = mDecoderReader->ReadMetadata(&mediaInfo, getter_Transfers(tags)); if (NS_FAILED(rv)) { ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent); return; } if (!mDecoderReader->HasAudio()) { ReportFailureOnMainThread(WebAudioDecodeJob::NoAudio); return; } while (mDecoderReader->DecodeAudioData()) { // consume all of the buffer continue; } mDecoderReader->OnDecodeThreadFinish(); MediaQueue<AudioData>& audioQueue = mDecoderReader->AudioQueue(); uint32_t frameCount = audioQueue.FrameCount(); uint32_t channelCount = mediaInfo.mAudio.mChannels; uint32_t sampleRate = mediaInfo.mAudio.mRate; if (!frameCount || !channelCount || !sampleRate) { ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent); return; } const uint32_t destSampleRate = mDecodeJob.mContext->SampleRate(); AutoResampler resampler; uint32_t resampledFrames = frameCount; if (sampleRate != destSampleRate) { resampledFrames = static_cast<uint32_t>( static_cast<uint64_t>(destSampleRate) * static_cast<uint64_t>(frameCount) / static_cast<uint64_t>(sampleRate) ); resampler = speex_resampler_init(channelCount, sampleRate, destSampleRate, SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr); speex_resampler_skip_zeros(resampler); resampledFrames += speex_resampler_get_output_latency(resampler); } // Allocate the channel buffers. Note that if we end up resampling, we may // write fewer bytes than mResampledFrames to the output buffer, in which // case mWriteIndex will tell us how many valid samples we have. static const fallible_t fallible = fallible_t(); bool memoryAllocationSuccess = true; if (!mDecodeJob.mChannelBuffers.SetLength(channelCount)) { memoryAllocationSuccess = false; } else { for (uint32_t i = 0; i < channelCount; ++i) { mDecodeJob.mChannelBuffers[i] = new(fallible) float[resampledFrames]; if (!mDecodeJob.mChannelBuffers[i]) { memoryAllocationSuccess = false; break; } } } if (!memoryAllocationSuccess) { ReportFailureOnMainThread(WebAudioDecodeJob::UnknownError); return; } nsAutoPtr<AudioData> audioData; while ((audioData = audioQueue.PopFront())) { audioData->EnsureAudioBuffer(); // could lead to a copy :( AudioDataValue* bufferData = static_cast<AudioDataValue*> (audioData->mAudioBuffer->Data()); if (sampleRate != destSampleRate) { const uint32_t maxOutSamples = resampledFrames - mDecodeJob.mWriteIndex; for (uint32_t i = 0; i < audioData->mChannels; ++i) { uint32_t inSamples = audioData->mFrames; uint32_t outSamples = maxOutSamples; WebAudioUtils::SpeexResamplerProcess( resampler, i, &bufferData[i * audioData->mFrames], &inSamples, mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex, &outSamples); if (i == audioData->mChannels - 1) { mDecodeJob.mWriteIndex += outSamples; MOZ_ASSERT(mDecodeJob.mWriteIndex <= resampledFrames); MOZ_ASSERT(inSamples == audioData->mFrames); } } } else { for (uint32_t i = 0; i < audioData->mChannels; ++i) { ConvertAudioSamples(&bufferData[i * audioData->mFrames], mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex, audioData->mFrames); if (i == audioData->mChannels - 1) { mDecodeJob.mWriteIndex += audioData->mFrames; } } } } if (sampleRate != destSampleRate) { uint32_t inputLatency = speex_resampler_get_input_latency(resampler); const uint32_t maxOutSamples = resampledFrames - mDecodeJob.mWriteIndex; for (uint32_t i = 0; i < channelCount; ++i) { uint32_t inSamples = inputLatency; uint32_t outSamples = maxOutSamples; WebAudioUtils::SpeexResamplerProcess( resampler, i, (AudioDataValue*)nullptr, &inSamples, mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex, &outSamples); if (i == channelCount - 1) { mDecodeJob.mWriteIndex += outSamples; MOZ_ASSERT(mDecodeJob.mWriteIndex <= resampledFrames); MOZ_ASSERT(inSamples == inputLatency); } } } mPhase = PhaseEnum::AllocateBuffer; RunNextPhase(); }
ThreadSharedFloatArrayBufferList* AudioBuffer::GetThreadSharedChannelsForRate(JSContext* aJSContext, uint32_t aRate, uint32_t* aLength) { if (mResampledChannels && mResampledChannelsRate == aRate) { // return cached data *aLength = mResampledChannelsLength; return mResampledChannels; } if (!mSharedChannels) { // Steal JS data mSharedChannels = StealJSArrayDataIntoThreadSharedFloatArrayBufferList(aJSContext, mJSChannels); } if (mSampleRate == aRate) { *aLength = mLength; return mSharedChannels; } mResampledChannels = new ThreadSharedFloatArrayBufferList(NumberOfChannels()); double newLengthD = ceil(Duration()*aRate); uint32_t newLength = uint32_t(newLengthD); *aLength = newLength; double size = sizeof(float)*NumberOfChannels()*newLengthD; if (size != uint32_t(size)) { return mResampledChannels; } float* outputData = static_cast<float*>(malloc(uint32_t(size))); if (!outputData) { nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(mContext->GetParentObject()); nsIDocument* doc = nullptr; if (pWindow) { doc = pWindow->GetExtantDoc(); } nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, "Media", doc, nsContentUtils::eDOM_PROPERTIES, "MediaBufferSourceNodeResampleOutOfMemory"); return mResampledChannels; } SpeexResamplerState* resampler = speex_resampler_init(NumberOfChannels(), mSampleRate, aRate, SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr); for (uint32_t i = 0; i < NumberOfChannels(); ++i) { const float* inputData = mSharedChannels->GetData(i); uint32_t inSamples = mLength; uint32_t outSamples = newLength; speex_resampler_process_float(resampler, i, inputData, &inSamples, outputData, &outSamples); mResampledChannels->SetData(i, i == 0 ? outputData : nullptr, outputData); outputData += newLength; } speex_resampler_destroy(resampler); mResampledChannelsRate = aRate; mResampledChannelsLength = newLength; return mResampledChannels; }
void BE_ST_InitAudio(void) { g_sdlAudioSubsystemUp = false; g_sdlEmulatedOPLChipReady = false; int inSampleRate = BE_Cross_GetSelectedGameVerSampleRate(); bool doDigitized = (inSampleRate != 0); if (!doDigitized) inSampleRate = OPL_SAMPLE_RATE; if (g_refKeenCfg.sndSubSystem) { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { BE_Cross_LogMessage(BE_LOG_MSG_WARNING, "SDL audio system initialization failed,\n%s\n", SDL_GetError()); } else { g_sdlAudioSpec.freq = g_refKeenCfg.sndSampleRate; #ifdef MIXER_SAMPLE_FORMAT_FLOAT g_sdlAudioSpec.format = AUDIO_F32SYS; #elif (defined MIXER_SAMPLE_FORMAT_SINT16) g_sdlAudioSpec.format = AUDIO_S16SYS; #endif g_sdlAudioSpec.channels = 1; // Should be some power-of-two roughly proportional to the sample rate; Using 1024 for 48000Hz. for (g_sdlAudioSpec.samples = 1; g_sdlAudioSpec.samples < g_refKeenCfg.sndSampleRate/64; g_sdlAudioSpec.samples *= 2) { } if (doDigitized) g_sdlAudioSpec.callback = (g_refKeenCfg.sndSampleRate == inSampleRate) ? BEL_ST_Simple_DigiCallBack : BEL_ST_Resampling_DigiCallBack; else g_sdlAudioSpec.callback = ((g_refKeenCfg.sndSampleRate == inSampleRate) || !g_refKeenCfg.oplEmulation) ? BEL_ST_Simple_EmuCallBack : BEL_ST_Resampling_EmuCallBack; g_sdlAudioSpec.userdata = NULL; if (SDL_OpenAudio(&g_sdlAudioSpec, NULL)) { BE_Cross_LogMessage(BE_LOG_MSG_WARNING, "Cannot open SDL audio device,\n%s\n", SDL_GetError()); SDL_QuitSubSystem(SDL_INIT_AUDIO); } else { #ifdef REFKEEN_CONFIG_THREADS g_sdlCallbackMutex = SDL_CreateMutex(); if (!g_sdlCallbackMutex) { BE_Cross_LogMessage(BE_LOG_MSG_ERROR, "Cannot create recursive mutex for SDL audio callback,\n%s\nClosing SDL audio subsystem\n", SDL_GetError()); SDL_CloseAudio(); SDL_QuitSubSystem(SDL_INIT_AUDIO); } else #endif { BE_Cross_LogMessage(BE_LOG_MSG_NORMAL, "Audio subsystem initialized, requested spec: freq %d, format %u, channels %d, samples %u\n", (int)g_sdlAudioSpec.freq, (unsigned int)g_sdlAudioSpec.format, (int)g_sdlAudioSpec.channels, (unsigned int)g_sdlAudioSpec.samples); g_sdlAudioSubsystemUp = true; } } } } // If the audio subsystem is off, let us simulate a byte rate // of 1000Hz (same as SDL_GetTicks() time units) if (!g_sdlAudioSubsystemUp) { g_sdlAudioSpec.freq = doDigitized ? inSampleRate : (NUM_OF_BYTES_FOR_SOUND_CALLBACK_WITH_DISABLED_SUBSYSTEM / sizeof(BE_ST_SndSample_T)); g_sdlAudioSpec.callback = doDigitized ? BEL_ST_Resampling_DigiCallBack : BEL_ST_Resampling_EmuCallBack; return; } if (g_refKeenCfg.oplEmulation) { YM3812Init(1, 3579545, OPL_SAMPLE_RATE); g_sdlEmulatedOPLChipReady = true; } if ((doDigitized || g_sdlEmulatedOPLChipReady) && (g_sdlAudioSpec.freq != inSampleRate)) { // Should allocate this first, for g_sdlSrcData.data_in g_sdlMiscOutNumOfSamples = 2*g_sdlAudioSpec.samples; g_sdlMiscOutSamples = (BE_ST_SndSample_T *)malloc(sizeof(BE_ST_SndSample_T) * g_sdlMiscOutNumOfSamples); if (g_sdlMiscOutSamples == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: Out of memory! (Failed to allocate g_sdlMiscOutSamples.)"); #ifndef REFKEEN_RESAMPLER_NONE if (g_refKeenCfg.useResampler) { #if (!defined REFKEEN_RESAMPLER_LIBRESAMPLE) && (!defined REFKEEN_RESAMPLER_LIBAVCODEC) char errMsg[160]; #endif #if (defined REFKEEN_RESAMPLER_LIBSWRESAMPLE) g_sdlSwrContext = swr_alloc_set_opts( NULL, // allocating a new context AV_CH_LAYOUT_MONO, // out channels layout AV_SAMPLE_FMT_S16, // out format g_sdlAudioSpec.freq, // out rate AV_CH_LAYOUT_MONO, // in channels layout AV_SAMPLE_FMT_S16, // in format inSampleRate, // in rate 0, NULL ); if (g_sdlSwrContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: swr_alloc_set_opts failed!"); int error = swr_init(g_sdlSwrContext); if (error != 0) { // av_err2str requires libavutil/libavutil-ffmpeg, so don't convert code to string snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: swr_init failed! Error code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBAVRESAMPLE) g_sdlAvAudioResampleContext = avresample_alloc_context(); if (g_sdlAvAudioResampleContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: avresample_alloc_context failed!"); av_opt_set_int(g_sdlAvAudioResampleContext, "in_channel_layout", AV_CH_LAYOUT_MONO, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_channel_layout", AV_CH_LAYOUT_MONO, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "in_sample_rate", inSampleRate, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_sample_rate", g_sdlAudioSpec.freq, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); int error = avresample_open(g_sdlAvAudioResampleContext); if (error != 0) { // av_err2str requires libavutil/libavutil-ffmpeg, so don't convert code to string snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: swr_init failed! Error code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBAVCODEC) avcodec_register_all(); g_sdlAvResampleContext = av_resample_init( g_sdlAudioSpec.freq, // out rate inSampleRate, // in rate 16, // filter length 10, // phase count 0, // linear FIR filter 1.0 // cutoff frequency ); if (g_sdlAvResampleContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: av_resample_init failed!"); #elif (defined REFKEEN_RESAMPLER_LIBRESAMPLE) g_sdlResampleFactor = (double)g_sdlAudioSpec.freq/inSampleRate; g_sdlResampleHandle = resample_open(0, g_sdlResampleFactor, g_sdlResampleFactor); if (g_sdlResampleHandle == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: resample_open failed!"); #elif (defined REFKEEN_RESAMPLER_LIBSOXR) soxr_io_spec_t io_spec = soxr_io_spec(SOXR_INT16, SOXR_INT16); soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LQ, 0); // Default quality spec adds an audible latency for resampling to 8000Hz soxr_error_t error; g_sdlSoxr = soxr_create( inSampleRate, // in rate g_sdlAudioSpec.freq, // out rate 1, // channels &error, &io_spec, &q_spec, NULL // runtime spec ); if (g_sdlSoxr == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: soxr_create failed!\nError: %s", soxr_strerror(error)); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBSPEEXDSP) int error; g_sdlSpeexResamplerState = speex_resampler_init( 1, // channels inSampleRate, // in rate g_sdlAudioSpec.freq, // out rate 0, // quality in the range 0-10 (10 is higher) &error ); if (g_sdlSpeexResamplerState == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: speex_resampler_init failed! Error code: %d\nError: %s", error, speex_resampler_strerror(error)); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBSAMPLERATE) int error; g_sdlSrcResampler = src_new(SRC_SINC_FASTEST, 1, &error); if (g_sdlSrcResampler == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: src_new failed!\nError code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } g_sdlSrcData.data_in = doDigitized ? g_sdlMiscOutSamples : g_sdlALOutSamples; g_sdlSrcData.src_ratio = (double)g_sdlAudioSpec.freq / inSampleRate; #endif } else #endif // REFKEEN_RESAMPLER_NONE { // The sum of all entries should be g_sdlAudioSpec.freq, // "uniformly" distributed over g_sdlALSampleRateConvTable g_sdlSampleRateConvTable = (int *)malloc(sizeof(int) * inSampleRate); if (g_sdlSampleRateConvTable == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: Failed to allocate memory for sample rate conversion!"); g_sdlSampleRateConvTableSize = inSampleRate; for (int i = 0; i < inSampleRate; ++i) { // Using uint64_t cause an overflow is possible g_sdlSampleRateConvTable[i] = ((uint64_t)(i+1)*(uint64_t)g_sdlAudioSpec.freq/inSampleRate)-(uint64_t)i*(uint64_t)g_sdlAudioSpec.freq/inSampleRate; } g_sdlSampleRateConvCurrIndex = 0; g_sdlSampleRateConvCounter = 0; } } }
JNIEXPORT jint JNICALL Java_com_zebra_emc_voip_audiotest_Speex_resample (JNIEnv * env, jclass obj, jstring path_in, jstring path_out, jint channels, jint sample_rate_in, jint sample_rate_out, jint quality) { // size in samples uint32_t in_size_in_sample; // size in samples uint32_t out_size_in_sample; // size in bytes (assumption: 2bytes/sample) uint32_t in_size; // size in bytes (assumption: 2bytes/sample) uint32_t out_size; short *in = NULL; short *out = NULL; FILE *fin = NULL; FILE *fout = NULL; SpeexResamplerState *st = NULL; if((channels != 1) && (channels !=2)) return SPEEX_ERROR; const char *native_path = (*env)->GetStringUTFChars(env, path_in, 0); fin = fopen(native_path, "rb"); (*env)->ReleaseStringUTFChars(env, path_in, native_path); if(NULL == fin) return SPEEX_ERROR; native_path = (*env)->GetStringUTFChars(env, path_out, 0); fout = fopen(native_path, "w+b"); (*env)->ReleaseStringUTFChars(env, path_out, native_path); if(NULL == fout) { fclose(fin); return SPEEX_ERROR; } if(NULL == (st = speex_resampler_init(channels, sample_rate_in, sample_rate_out, SPEEX_RESAMPLER_QUALITY_DEFAULT, NULL))) return SPEEX_ERROR; in_size_in_sample = ((sample_rate_in * TIMEDURATION) / 1000) << (channels == 2 ? 1 : 0); in_size = in_size_in_sample * sizeof(short); out_size_in_sample = ((sample_rate_out * TIMEDURATION) / 1000) << (channels == 2 ? 1 : 0); out_size = out_size_in_sample * sizeof(short); in = malloc(in_size * sizeof(short)); out = malloc(out_size * sizeof(short)); uint32_t rd_len; int end_of_file = 0; int ret = SPEEX_SUCCESS; while (!end_of_file) { rd_len = fread(in, sizeof(short), in_size_in_sample, fin); if (rd_len < in_size_in_sample) { if(!feof(fin)) { ret = SPEEX_ERROR; break; } // the end of the file is reached else end_of_file = 1; } if(RESAMPLER_ERR_SUCCESS != speex_resampler_process_int(st, 0, in, &in_size_in_sample, out, &out_size_in_sample)) { ret = SPEEX_ERROR; break; } fwrite(out, sizeof(short), out_size_in_sample, fout); } speex_resampler_destroy(st); free(in); free(out); fclose(fin); fclose(fout); return ret; }
AudioOutputSpeech::AudioOutputSpeech(boost::shared_ptr<ClientUser> user, MessageHandler::UDPMessageType type) : AudioOutputUser(user->qsName) { int err; p = user; umtType = type; unsigned int srate = 0; cCodec = NULL; cdDecoder = NULL; if (umtType != MessageHandler::UDPVoiceSpeex) { srate = SAMPLE_RATE; iFrameSize = srate / 100; dsSpeex = NULL; } else { speex_bits_init(&sbBits); dsSpeex = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB)); int iArg=1; speex_decoder_ctl(dsSpeex, SPEEX_SET_ENH, &iArg); speex_decoder_ctl(dsSpeex, SPEEX_GET_FRAME_SIZE, &iFrameSize); speex_decoder_ctl(dsSpeex, SPEEX_GET_SAMPLING_RATE, &srate); } if (srate != SAMPLE_RATE) srs = speex_resampler_init(1, srate, SAMPLE_RATE, 3, &err); else srs = NULL; iOutputSize = static_cast<unsigned int>(ceilf(static_cast<float>(iFrameSize * SAMPLE_RATE) / static_cast<float>(SAMPLE_RATE))); iBufferOffset = iBufferFilled = iLastConsume = 0; bLastAlive = true; iMissCount = 0; iMissedFrames = 0; ucFlags = 0xFF; jbJitter = jitter_buffer_init(iFrameSize); int margin = g.s.iJitterBufferSize * iFrameSize; jitter_buffer_ctl(jbJitter, JITTER_BUFFER_SET_MARGIN, &margin); fFadeIn = new float[iFrameSize]; fFadeOut = new float[iFrameSize]; float mul = static_cast<float>(M_PI / (2.0 * static_cast<double>(iFrameSize))); for (unsigned int i=0;i<iFrameSize;++i) fFadeIn[i] = fFadeOut[iFrameSize-i-1] = sinf(static_cast<float>(i) * mul); }