コード例 #1
0
ファイル: LiuWestParticleFilter.cpp プロジェクト: cran/Boom
 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_);
   }
 }
コード例 #2
0
ファイル: Sound.cpp プロジェクト: ZappoMan/hifi
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);
    }
}
コード例 #3
0
	void operator()(
		const float baseband_sample
	) {
		resampler(baseband_sample,
			[this](const float interpolated_sample) {
				this->resampler_callback(interpolated_sample);
			}
		);
	}
コード例 #4
0
ファイル: resamplertest.cpp プロジェクト: alexzah/ring-daemon
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));
}
コード例 #5
0
ファイル: resamplertest.cpp プロジェクト: alexzah/ring-daemon
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));
}
コード例 #6
0
ファイル: AudioInjector.cpp プロジェクト: disigma/hifi
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);
}
コード例 #7
0
ファイル: Sound.cpp プロジェクト: AlphaStaxLLC/hifi
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);
}
コード例 #8
0
ファイル: test_resampler.cpp プロジェクト: kinetiknz/cubeb
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);
}
コード例 #9
0
ファイル: SBSMSEffect.cpp プロジェクト: QuincyPYoung/audacity
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;
}
コード例 #10
0
ファイル: wsmsgridder.cpp プロジェクト: o-smirnov/wsclean-1.9
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;
}
コード例 #11
0
ファイル: wsmsgridder.cpp プロジェクト: o-smirnov/wsclean-1.9
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;
}
コード例 #12
0
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);
    }
}