Matrix LiuWestParticleFilter::state_distribution(RNG *rng) const { if (rng) { Resampler resampler(particle_weights(), false); return to_matrix(resampler(state_particles_, -1, *rng)); } else { return to_matrix(state_particles_); } }
void SoundProcessor::downSample(const QByteArray& rawAudioByteArray, int sampleRate) { // we want to convert it to the format that the audio-mixer wants // which is signed, 16-bit, 24Khz if (sampleRate == AudioConstants::SAMPLE_RATE) { // no resampling needed _data = rawAudioByteArray; } else { int numChannels = _isAmbisonic ? AudioConstants::AMBISONIC : (_isStereo ? AudioConstants::STEREO : AudioConstants::MONO); AudioSRC resampler(sampleRate, AudioConstants::SAMPLE_RATE, numChannels); // resize to max possible output int numSourceFrames = rawAudioByteArray.size() / (numChannels * sizeof(AudioConstants::AudioSample)); int maxDestinationFrames = resampler.getMaxOutput(numSourceFrames); int maxDestinationBytes = maxDestinationFrames * numChannels * sizeof(AudioConstants::AudioSample); _data.resize(maxDestinationBytes); int numDestinationFrames = resampler.render((int16_t*)rawAudioByteArray.data(), (int16_t*)_data.data(), numSourceFrames); // truncate to actual output int numDestinationBytes = numDestinationFrames * numChannels * sizeof(AudioConstants::AudioSample); _data.resize(numDestinationBytes); } }
void operator()( const float baseband_sample ) { resampler(baseband_sample, [this](const float interpolated_sample) { this->resampler_callback(interpolated_sample); } ); }
void ResamplerTest::testUpsamplingTriangle() { generateTriangularSignal(); std::cout << "Test Upsampling Triangle" << std::endl; Resampler resampler(44100); performUpsampling(resampler); AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); tmpInputBuffer.copy(inputBuffer); std::cout << "Input Buffer" << std::endl; print_buffer(*tmpInputBuffer.getChannel(0)); tmpOutputBuffer.copy(outputBuffer); std::cout << "Output Buffer" << std::endl; print_buffer(*tmpOutputBuffer.getChannel(0)); }
void ResamplerTest::testUpsamplingRamp() { // generate input samples and store them in inputBuffer generateRamp(); std::cout << "Test Upsampling Ramp" << std::endl; Resampler resampler(44100); performUpsampling(resampler); AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); tmpInputBuffer.copy(inputBuffer); std::cout << "Input Buffer" << std::endl; print_buffer(*tmpInputBuffer.getChannel(0)); tmpOutputBuffer.copy(outputBuffer); std::cout << "Output Buffer" << std::endl; print_buffer(*tmpOutputBuffer.getChannel(0)); }
AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float volume, const float stretchFactor, const glm::vec3 position) { if (soundUrl.isEmpty()) { return NULL; } auto soundCache = DependencyManager::get<SoundCache>(); if (soundCache.isNull()) { return NULL; } SharedSoundPointer sound = soundCache->getSound(QUrl(soundUrl)); if (sound.isNull() || !sound->isReady()) { return NULL; } AudioInjectorOptions options; options.stereo = sound->isStereo(); options.position = position; options.volume = volume; QByteArray samples = sound->getByteArray(); if (stretchFactor == 1.0f) { return playSoundAndDelete(samples, options, NULL); } const int standardRate = AudioConstants::SAMPLE_RATE; const int resampledRate = standardRate * stretchFactor; const int channelCount = sound->isStereo() ? 2 : 1; AudioSRC resampler(standardRate, resampledRate, channelCount); const int nInputFrames = samples.size() / (channelCount * sizeof(int16_t)); const int maxOutputFrames = resampler.getMaxOutput(nInputFrames); QByteArray resampled(maxOutputFrames * channelCount * sizeof(int16_t), '\0'); int nOutputFrames = resampler.render(reinterpret_cast<const int16_t*>(samples.data()), reinterpret_cast<int16_t*>(resampled.data()), nInputFrames); Q_UNUSED(nOutputFrames); return playSoundAndDelete(resampled, options, NULL); }
void Sound::downSample(const QByteArray& rawAudioByteArray) { // assume that this was a RAW file and is now an array of samples that are // signed, 16-bit, 48Khz // we want to convert it to the format that the audio-mixer wants // which is signed, 16-bit, 24Khz int numChannels = _isStereo ? 2 : 1; AudioSRC resampler(48000, AudioConstants::SAMPLE_RATE, numChannels); // resize to max possible output int numSourceFrames = rawAudioByteArray.size() / (numChannels * sizeof(AudioConstants::AudioSample)); int maxDestinationFrames = resampler.getMaxOutput(numSourceFrames); int maxDestinationBytes = maxDestinationFrames * numChannels * sizeof(AudioConstants::AudioSample); _byteArray.resize(maxDestinationBytes); int numDestinationFrames = resampler.render((int16_t*)rawAudioByteArray.data(), (int16_t*)_byteArray.data(), numSourceFrames); // truncate to actual output int numDestinationBytes = numDestinationFrames * numChannels * sizeof(AudioConstants::AudioSample); _byteArray.resize(numDestinationBytes); }
void test_resampler_one_way(uint32_t channels, uint32_t source_rate, uint32_t target_rate, float chunk_duration) { size_t chunk_duration_in_source_frames = static_cast<uint32_t>(ceil(chunk_duration * source_rate / 1000.)); float resampling_ratio = static_cast<float>(source_rate) / target_rate; cubeb_resampler_speex_one_way<T> resampler(channels, source_rate, target_rate, 3); auto_array<T> source(channels * source_rate * 10); auto_array<T> destination(channels * target_rate * 10); auto_array<T> expected(channels * target_rate * 10); uint32_t phase_index = 0; uint32_t offset = 0; const uint32_t buf_len = 2; /* seconds */ // generate a sine wave in each channel, at the source sample rate source.push_silence(channels * source_rate * buf_len); while(offset != source.length()) { float p = phase_index++ / static_cast<float>(source_rate); for (uint32_t j = 0; j < channels; j++) { source.data()[offset++] = 0.5 * sin(440. * 2 * PI * p); } } dump("input.raw", source.data(), source.length()); expected.push_silence(channels * target_rate * buf_len); // generate a sine wave in each channel, at the target sample rate. // Insert silent samples at the beginning to account for the resampler latency. offset = resampler.latency() * channels; for (uint32_t i = 0; i < offset; i++) { expected.data()[i] = 0.0f; } phase_index = 0; while (offset != expected.length()) { float p = phase_index++ / static_cast<float>(target_rate); for (uint32_t j = 0; j < channels; j++) { expected.data()[offset++] = 0.5 * sin(440. * 2 * PI * p); } } dump("expected.raw", expected.data(), expected.length()); // resample by chunk uint32_t write_offset = 0; destination.push_silence(channels * target_rate * buf_len); while (write_offset < destination.length()) { size_t output_frames = static_cast<uint32_t>(floor(chunk_duration_in_source_frames / resampling_ratio)); uint32_t input_frames = resampler.input_needed_for_output(output_frames); resampler.input(source.data(), input_frames); source.pop(nullptr, input_frames * channels); resampler.output(destination.data() + write_offset, std::min(output_frames, (destination.length() - write_offset) / channels)); write_offset += output_frames * channels; } dump("output.raw", destination.data(), expected.length()); // compare, taking the latency into account bool fuzzy_equal = true; for (uint32_t i = resampler.latency() + 1; i < expected.length(); i++) { float diff = fabs(expected.data()[i] - destination.data()[i]); if (diff > epsilon<T>(resampling_ratio)) { fprintf(stderr, "divergence at %d: %f %f (delta %f)\n", i, expected.data()[i], destination.data()[i], diff); fuzzy_equal = false; } } ASSERT_TRUE(fuzzy_equal); }
bool EffectSBSMS::Process() { bool bGoodResult = true; //Iterate over each track //Track::All is needed because this effect needs to introduce silence in the group tracks to keep sync this->CopyInputTracks(Track::All); // Set up mOutputTracks. TrackListIterator iter(mOutputTracks); Track* t; mCurTrackNum = 0; double maxDuration = 0.0; // Must sync if selection length will change bool mustSync = (rateStart != rateEnd); Slide rateSlide(rateSlideType,rateStart,rateEnd); Slide pitchSlide(pitchSlideType,pitchStart,pitchEnd); mTotalStretch = rateSlide.getTotalStretch(); t = iter.First(); while (t != NULL) { if (t->GetKind() == Track::Label && (t->GetSelected() || (mustSync && t->IsSyncLockSelected())) ) { if (!ProcessLabelTrack(t)) { bGoodResult = false; break; } } else if (t->GetKind() == Track::Wave && t->GetSelected() ) { WaveTrack* leftTrack = (WaveTrack*)t; //Get start and end times from track mCurT0 = leftTrack->GetStartTime(); mCurT1 = leftTrack->GetEndTime(); //Set the current bounds to whichever left marker is //greater and whichever right marker is less mCurT0 = wxMax(mT0, mCurT0); mCurT1 = wxMin(mT1, mCurT1); // Process only if the right marker is to the right of the left marker if (mCurT1 > mCurT0) { sampleCount start; sampleCount end; start = leftTrack->TimeToLongSamples(mCurT0); end = leftTrack->TimeToLongSamples(mCurT1); WaveTrack* rightTrack = NULL; if (leftTrack->GetLinked()) { double t; rightTrack = (WaveTrack*)(iter.Next()); //Adjust bounds by the right tracks markers t = rightTrack->GetStartTime(); t = wxMax(mT0, t); mCurT0 = wxMin(mCurT0, t); t = rightTrack->GetEndTime(); t = wxMin(mT1, t); mCurT1 = wxMax(mCurT1, t); //Transform the marker timepoints to samples start = leftTrack->TimeToLongSamples(mCurT0); end = leftTrack->TimeToLongSamples(mCurT1); mCurTrackNum++; // Increment for rightTrack, too. } sampleCount trackStart = leftTrack->TimeToLongSamples(leftTrack->GetStartTime()); sampleCount trackEnd = leftTrack->TimeToLongSamples(leftTrack->GetEndTime()); // SBSMS has a fixed sample rate - we just convert to its sample rate and then convert back float srTrack = leftTrack->GetRate(); float srProcess = bLinkRatePitch?srTrack:44100.0; // the resampler needs a callback to supply its samples ResampleBuf rb; sampleCount maxBlockSize = leftTrack->GetMaxBlockSize(); rb.blockSize = maxBlockSize; rb.buf = (audio*)calloc(rb.blockSize,sizeof(audio)); rb.leftTrack = leftTrack; rb.rightTrack = rightTrack?rightTrack:leftTrack; rb.leftBuffer = (float*)calloc(maxBlockSize,sizeof(float)); rb.rightBuffer = (float*)calloc(maxBlockSize,sizeof(float)); // Samples in selection sampleCount samplesIn = end-start; // Samples for SBSMS to process after resampling sampleCount samplesToProcess = (sampleCount) ((float)samplesIn*(srProcess/srTrack)); SlideType outSlideType; SBSMSResampleCB outResampleCB; sampleCount processPresamples = 0; sampleCount trackPresamples = 0; if(bLinkRatePitch) { rb.bPitch = true; outSlideType = rateSlideType; outResampleCB = resampleCB; rb.offset = start; rb.end = end; rb.iface = new SBSMSInterfaceSliding(&rateSlide,&pitchSlide, bPitchReferenceInput, samplesToProcess,0, NULL); } else { rb.bPitch = false; outSlideType = (srProcess==srTrack?SlideIdentity:SlideConstant); outResampleCB = postResampleCB; rb.ratio = srProcess/srTrack; rb.quality = new SBSMSQuality(&SBSMSQualityStandard); rb.resampler = new Resampler(resampleCB, &rb, srProcess==srTrack?SlideIdentity:SlideConstant); rb.sbsms = new SBSMS(rightTrack?2:1,rb.quality,true); rb.SBSMSBlockSize = rb.sbsms->getInputFrameSize(); rb.SBSMSBuf = (audio*)calloc(rb.SBSMSBlockSize,sizeof(audio)); processPresamples = wxMin(rb.quality->getMaxPresamples(), (long)((float)(start-trackStart)*(srProcess/srTrack))); trackPresamples = wxMin(start-trackStart, (long)((float)(processPresamples)*(srTrack/srProcess))); rb.offset = start - trackPresamples; rb.end = trackEnd; rb.iface = new SBSMSEffectInterface(rb.resampler, &rateSlide,&pitchSlide, bPitchReferenceInput, samplesToProcess,processPresamples, rb.quality); } Resampler resampler(outResampleCB,&rb,outSlideType); audio outBuf[SBSMSOutBlockSize]; float outBufLeft[2*SBSMSOutBlockSize]; float outBufRight[2*SBSMSOutBlockSize]; // Samples in output after SBSMS sampleCount samplesToOutput = rb.iface->getSamplesToOutput(); // Samples in output after resampling back sampleCount samplesOut = (sampleCount) ((float)samplesToOutput * (srTrack/srProcess)); // Duration in track time double duration = (mCurT1-mCurT0) * mTotalStretch; if(duration > maxDuration) maxDuration = duration; TimeWarper *warper = createTimeWarper(mCurT0,mCurT1,maxDuration,rateStart,rateEnd,rateSlideType); SetTimeWarper(warper); rb.outputLeftTrack = mFactory->NewWaveTrack(leftTrack->GetSampleFormat(), leftTrack->GetRate()); if(rightTrack) rb.outputRightTrack = mFactory->NewWaveTrack(rightTrack->GetSampleFormat(), rightTrack->GetRate()); long pos = 0; long outputCount = -1; // process while(pos<samplesOut && outputCount) { long frames; if(pos+SBSMSOutBlockSize>samplesOut) { frames = samplesOut - pos; } else { frames = SBSMSOutBlockSize; } outputCount = resampler.read(outBuf,frames); for(int i = 0; i < outputCount; i++) { outBufLeft[i] = outBuf[i][0]; if(rightTrack) outBufRight[i] = outBuf[i][1]; } pos += outputCount; rb.outputLeftTrack->Append((samplePtr)outBufLeft, floatSample, outputCount); if(rightTrack) rb.outputRightTrack->Append((samplePtr)outBufRight, floatSample, outputCount); double frac = (double)pos/(double)samplesOut; int nWhichTrack = mCurTrackNum; if(rightTrack) { nWhichTrack = 2*(mCurTrackNum/2); if (frac < 0.5) frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once. else { nWhichTrack++; frac -= 0.5; frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once. } } if (TrackProgress(nWhichTrack, frac)) return false; } rb.outputLeftTrack->Flush(); if(rightTrack) rb.outputRightTrack->Flush(); bool bResult = leftTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputLeftTrack, true, false, GetTimeWarper()); wxASSERT(bResult); // TO DO: Actually handle this. wxUnusedVar(bResult); if(rightTrack) { bResult = rightTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputRightTrack, true, false, GetTimeWarper()); wxASSERT(bResult); // TO DO: Actually handle this. } } mCurTrackNum++; } else if (mustSync && t->IsSyncLockSelected()) { t->SyncLockAdjust(mCurT1, mCurT0 + (mCurT1 - mCurT0) * mTotalStretch); } //Iterate to the next track t = iter.Next(); } if (bGoodResult) ReplaceProcessedTracks(bGoodResult); // Update selection mT0 = mCurT0; mT1 = mCurT0 + maxDuration; return bGoodResult; }
void WSMSGridder::Predict(double* real, double* imaginary) { if(imaginary==0 && IsComplex()) throw std::runtime_error("Missing imaginary in complex prediction"); if(imaginary!=0 && !IsComplex()) throw std::runtime_error("Imaginary specified in non-complex prediction"); MSData* msDataVector = new MSData[MeasurementSetCount()]; _hasFrequencies = false; for(size_t i=0; i!=MeasurementSetCount(); ++i) initializeMeasurementSet(i, msDataVector[i]); double minW = msDataVector[0].minW; double maxW = msDataVector[0].maxW; for(size_t i=1; i!=MeasurementSetCount(); ++i) { if(msDataVector[i].minW < minW) minW = msDataVector[i].minW; if(msDataVector[i].maxW > maxW) maxW = msDataVector[i].maxW; } _gridder = std::unique_ptr<WStackingGridder>(new WStackingGridder(_actualInversionWidth, _actualInversionHeight, _actualPixelSizeX, _actualPixelSizeY, _cpuCount, _imageBufferAllocator, AntialiasingKernelSize(), OverSamplingFactor())); _gridder->SetGridMode(_gridMode); if(_denormalPhaseCentre) _gridder->SetDenormalPhaseCentre(_phaseCentreDL, _phaseCentreDM); _gridder->SetIsComplex(IsComplex()); //_imager->SetImageConjugatePart(Polarization() == Polarization::YX && IsComplex()); _gridder->PrepareWLayers(WGridSize(), double(_memSize)*(7.0/10.0), minW, maxW); if(Verbose()) { for(size_t i=0; i!=MeasurementSetCount(); ++i) countSamplesPerLayer(msDataVector[i]); } double *resizedReal = 0, *resizedImag = 0; if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight) { FFTResampler resampler(ImageWidth(), ImageHeight(), _actualInversionWidth, _actualInversionHeight, _cpuCount); if(imaginary == 0) { resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resampler.RunSingle(real, resizedReal); real = resizedReal; } else { resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resizedImag = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resampler.Start(); resampler.AddTask(real, resizedReal); resampler.AddTask(imaginary, resizedImag); resampler.Finish(); real = resizedReal; imaginary = resizedImag; } } for(size_t pass=0; pass!=_gridder->NPasses(); ++pass) { std::cout << "Fourier transforms for pass " << pass << "... "; if(Verbose()) std::cout << '\n'; else std::cout << std::flush; if(imaginary == 0) _gridder->InitializePrediction(real); else _gridder->InitializePrediction(real, imaginary); _gridder->StartPredictionPass(pass); std::cout << "Predicting...\n"; for(size_t i=0; i!=MeasurementSetCount(); ++i) predictMeasurementSet(msDataVector[i]); } if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight) { _imageBufferAllocator->Free(resizedReal); _imageBufferAllocator->Free(resizedImag); } size_t totalRowsWritten = 0, totalMatchingRows = 0; for(size_t i=0; i!=MeasurementSetCount(); ++i) { totalRowsWritten += msDataVector[i].totalRowsProcessed; totalMatchingRows += msDataVector[i].matchingRows; } std::cout << "Total rows written: " << totalRowsWritten; if(totalMatchingRows != 0) std::cout << " (overhead: " << std::max(0.0, round(totalRowsWritten * 100.0 / totalMatchingRows - 100.0)) << "%)"; std::cout << '\n'; delete[] msDataVector; }
void WSMSGridder::Invert() { MSData* msDataVector = new MSData[MeasurementSetCount()]; _hasFrequencies = false; for(size_t i=0; i!=MeasurementSetCount(); ++i) initializeMeasurementSet(i, msDataVector[i]); double minW = msDataVector[0].minW; double maxW = msDataVector[0].maxW; for(size_t i=1; i!=MeasurementSetCount(); ++i) { if(msDataVector[i].minW < minW) minW = msDataVector[i].minW; if(msDataVector[i].maxW > maxW) maxW = msDataVector[i].maxW; } _gridder = std::unique_ptr<WStackingGridder>(new WStackingGridder(_actualInversionWidth, _actualInversionHeight, _actualPixelSizeX, _actualPixelSizeY, _cpuCount, _imageBufferAllocator, AntialiasingKernelSize(), OverSamplingFactor())); _gridder->SetGridMode(_gridMode); if(_denormalPhaseCentre) _gridder->SetDenormalPhaseCentre(_phaseCentreDL, _phaseCentreDM); _gridder->SetIsComplex(IsComplex()); //_imager->SetImageConjugatePart(Polarization() == Polarization::YX && IsComplex()); _gridder->PrepareWLayers(WGridSize(), double(_memSize)*(7.0/10.0), minW, maxW); if(Verbose()) { for(size_t i=0; i!=MeasurementSetCount(); ++i) countSamplesPerLayer(msDataVector[i]); } _totalWeight = 0.0; for(size_t pass=0; pass!=_gridder->NPasses(); ++pass) { std::cout << "Gridding pass " << pass << "... "; if(Verbose()) std::cout << '\n'; else std::cout << std::flush; _inversionWorkLane.reset(new ao::lane<InversionWorkItem>(2048)); _gridder->StartInversionPass(pass); for(size_t i=0; i!=MeasurementSetCount(); ++i) { _inversionWorkLane->clear(); MSData& msData = msDataVector[i]; const MultiBandData selectedBand(msData.SelectedBand()); boost::thread thread(&WSMSGridder::workThreadParallel, this, &selectedBand); gridMeasurementSet(msData); _inversionWorkLane->write_end(); thread.join(); } _inversionWorkLane.reset(); std::cout << "Fourier transforms...\n"; _gridder->FinishInversionPass(); } if(Verbose()) { size_t totalRowsRead = 0, totalMatchingRows = 0; for(size_t i=0; i!=MeasurementSetCount(); ++i) { totalRowsRead += msDataVector[i].totalRowsProcessed; totalMatchingRows += msDataVector[i].matchingRows; } std::cout << "Total rows read: " << totalRowsRead; if(totalMatchingRows != 0) std::cout << " (overhead: " << std::max(0.0, round(totalRowsRead * 100.0 / totalMatchingRows - 100.0)) << "%)"; std::cout << '\n'; } if(NormalizeForWeighting()) _gridder->FinalizeImage(1.0/_totalWeight, false); else { std::cout << "Not dividing by normalization factor of " << _totalWeight << ".\n"; _gridder->FinalizeImage(1.0, true); } if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight) { FFTResampler resampler(_actualInversionWidth, _actualInversionHeight, ImageWidth(), ImageHeight(), _cpuCount); if(IsComplex()) { double *resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); double *resizedImag = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resampler.Start(); resampler.AddTask(_gridder->RealImage(), resizedReal); resampler.AddTask(_gridder->ImaginaryImage(), resizedImag); resampler.Finish(); _gridder->ReplaceRealImageBuffer(resizedReal); _gridder->ReplaceImaginaryImageBuffer(resizedImag); } else { double *resized = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resampler.RunSingle(_gridder->RealImage(), resized); _gridder->ReplaceRealImageBuffer(resized); } } delete[] msDataVector; }
static void test_resampler(void) { std::string fbody("sweep_440-3520_1s"); mcon::Vector<double> input; mfio::Wave wave; wave.Read(fbody + std::string(".wav"), input); const int baseFs = wave.GetSamplingRate(); const int targetFs = 16000; const double fp = 0.35; const double fs = 0.45; masp::Resampler resampler(targetFs, baseFs, fp, fs); resampler.MakeFilterByWindowType(masp::Resampler::HANNING); { mcon::Vector<double> coefs; resampler.GetCoefficients(coefs); LOG("Length=%d\n", static_cast<int>(coefs.GetLength())); } { mcon::Vector<double> output; resampler.Convert(output, input); output *= 32767.0/output.GetMaximumAbsolute(); mfio::Wave w(targetFs, wave.GetNumChannels(), wave.GetBitDepth()); w.Write(fbody + std::string("_resampled1.wav"), output); } const double ripple = 0.01; const double decay = 80; resampler.MakeFilterBySpec(ripple, decay); { mcon::Vector<double> coefs; resampler.GetCoefficients(coefs); LOG("Length=%d\n", static_cast<int>(coefs.GetLength())); } { mcon::Vector<double> output; resampler.Convert(output, input); output *= 32767.0/output.GetMaximumAbsolute(); mfio::Wave w(targetFs, wave.GetNumChannels(), wave.GetBitDepth()); w.Write(fbody + std::string("_resampled2.wav"), output); } // サンプルの数を変更する // ==> 実質的に周波数変換? // ==> 違う気がする... { const int N = 100; const double ratio = 1.5; const double fp = 0.35; const double fs = 0.45; const double ripple = 0.01; const double decay = 80; mcon::Vector<double> src(N); for (int k = 0; k < N; ++k) { src[k] = k; } resampler.Initialize(static_cast<int>(ratio * N), N, fp, fs); resampler.MakeFilterBySpec(ripple, decay); mcon::Vector<double> dst; resampler.Convert(dst, src); mfio::Csv::Write("sample_count_convert.csv", dst); } }