void TranscriptionToolBar::OnEndOff(wxCommandEvent & WXUNUSED(event))
{

   //If IO is busy, abort immediately
   if (gAudioIO->IsBusy()){
      SetButton(false,mButtons[TTB_EndOff]);
      return;
   }
   mVk->AdjustThreshold(GetSensitivity());
   AudacityProject *p = GetActiveProject();

   auto t = *p->GetTracks()->Any< const WaveTrack >().begin();
   if(t) {
      auto wt = static_cast<const WaveTrack*>(t);
      sampleCount start, len;
      GetSamples(wt, &start, &len);

      //Adjust length to end if selection is null
      if(len == 0) {
         len = start;
         start = 0;
      }
      auto newEnd = mVk->OffBackward(*wt, start + len, len);
      double newpos = newEnd.as_double() / wt->GetRate();

      p->SetSel1(newpos);
      p->RedrawProject();

      SetButton(false, mButtons[TTB_EndOff]);
   }
}
Пример #2
0
void TranscriptionToolBar::OnEndOn(wxCommandEvent & WXUNUSED(event))
{

   //If IO is busy, abort immediately
   if (gAudioIO->IsBusy()){
      SetButton(false,mButtons[TTB_EndOn]);
      return;
   }

   mVk->AdjustThreshold(GetSensitivity());
   AudacityProject *p = GetActiveProject();
   TrackList *tl = p->GetTracks();
   TrackListOfKindIterator iter(Track::Wave, tl);

   Track *t = iter.First();   //Make a track
   if(t) {
      sampleCount start,len;
      GetSamples((WaveTrack*)t, &start,&len);

      //Adjust length to end if selection is null
      if(len == 0)
         {
            len = start;
            start = 0;
         }
      sampleCount newEnd = mVk->OnBackward(*(WaveTrack*)t,start+ len,len);
      double newpos = newEnd / ((WaveTrack*)t)->GetRate();

      p->SetSel1(newpos);
      p->RedrawProject();

      SetButton(false, mButtons[TTB_EndOn]);
   }
}
Пример #3
0
void TranscriptionToolBar::OnStartOff(wxCommandEvent & WXUNUSED(event))
{
   //If IO is busy, abort immediately
   if (gAudioIO->IsBusy()){
      SetButton(false,mButtons[TTB_StartOff]);
      return;
   }
   mVk->AdjustThreshold(GetSensitivity());
   AudacityProject *p = GetActiveProject();

   TrackList *tl = p->GetTracks();
   TrackListOfKindIterator iter(Track::Wave, tl);

   SetButton(false, mButtons[TTB_StartOff]);
   Track *t = iter.First();   //Make a track
   if(t) {
      auto wt = static_cast<const WaveTrack*>(t);
      sampleCount start, len;
      GetSamples(wt, &start, &len);

      //Adjust length to end if selection is null
      //if(len == 0)
      //len = wt->GetSequence()->GetNumSamples()-start;

      auto newstart = mVk->OffForward(*wt, start, len);
      double newpos = newstart.as_double() / wt->GetRate();

      p->SetSel0(newpos);
      p->RedrawProject();

      SetButton(false, mButtons[TTB_StartOn]);
   }
}
Пример #4
0
//-----------------------------------------------------------------------
Duration AudioClip::Length() const
{
    POMDOG_ASSERT(nativeAudioClip);
    auto samples = GetSamples(nativeAudioClip->SizeInBytes(), bitsPerSample, channels);
    auto sampleDuration = GetSampleDuration(samples, sampleRate);
    return std::move(sampleDuration);
}
void TranscriptionToolBar::OnStartOff(wxCommandEvent & WXUNUSED(event))
{
   //If IO is busy, abort immediately
   if (gAudioIO->IsBusy()){
      SetButton(false,mButtons[TTB_StartOff]);
      return;
   }
   mVk->AdjustThreshold(GetSensitivity());
   AudacityProject *p = GetActiveProject();

   SetButton(false, mButtons[TTB_StartOff]);
   auto t = *p->GetTracks()->Any< const WaveTrack >().begin();
   if(t) {
      auto wt = static_cast<const WaveTrack*>(t);
      sampleCount start, len;
      GetSamples(wt, &start, &len);

      //Adjust length to end if selection is null
      //if(len == 0)
      //len = wt->GetSequence()->GetNumSamples()-start;

      auto newstart = mVk->OffForward(*wt, start, len);
      double newpos = newstart.as_double() / wt->GetRate();

      auto &selectedRegion = p->GetViewInfo().selectedRegion;
      selectedRegion.setT0( newpos );
      p->RedrawProject();

      SetButton(false, mButtons[TTB_StartOn]);
   }
}
Пример #6
0
Var* ff_fft(vfuncptr func, Var* arg)
{
	Var *real = NULL, *img = NULL;
	double* data;
	int i, j, n, x, y, z;
	COMPLEX *in, *out;

	Alist alist[4];
	alist[0]      = make_alist("real", ID_VAL, NULL, &real);
	alist[1]      = make_alist("img", ID_VAL, NULL, &img);
	alist[2].name = NULL;

	if (parse_args(func, arg, alist) == 0) return (NULL);

	if (real == NULL && img == NULL) {
		parse_error("%s: No real or imaginary objects specified\n", func->name);
		return (NULL);
	}
	x = GetSamples(V_SIZE(real), V_ORG(real));
	y = GetLines(V_SIZE(real), V_ORG(real));
	z = GetBands(V_SIZE(real), V_ORG(real));

	if (img == NULL && x == 2) {
		n   = y * z;
		in  = (COMPLEX*)calloc(n, sizeof(COMPLEX));
		out = (COMPLEX*)calloc(n, sizeof(COMPLEX));
		for (i = 0; i < y; i++) {
			for (j = 0; j < z; j++) {
				in[i].re = extract_double(real, cpos(0, i, j, real));
				in[i].im = extract_double(real, cpos(1, i, j, real));
			}
		}
	} else {
		n   = V_DSIZE(real);
		in  = (COMPLEX*)calloc(n, sizeof(COMPLEX));
		out = (COMPLEX*)calloc(n, sizeof(COMPLEX));
		for (i = 0; i < n; i++) {
			in[i].re = extract_double(real, i);
			in[i].im = (img == NULL ? 0.0 : extract_double(img, i));
		}
	}

	if (func->fdata == (void*)1) {
		fft(in, n, out);
	} else {
		rft(in, n, out);
	}

	data = (double*)calloc(n * 2, sizeof(double));

	for (i = 0; i < n; i++) {
		data[i * 2]     = out[i].re;
		data[i * 2 + 1] = out[i].im;
	}
	return (newVal(BSQ, 2, n, 1, DV_DOUBLE, data));
}
Пример #7
0
bool VSTEffect::Init()
{
   if (!mAEffect) {
      Load();
   }

   if (!mAEffect) {
      return false;
   }

   mBlockSize = 0;

   TrackListIterator iter(mOutputTracks);
   WaveTrack *left = (WaveTrack *) iter.First();
   while (left) {
      sampleCount lstart;
      sampleCount llen;

      GetSamples(left, &lstart, &llen);
      
      if (left->GetLinked()) {
         WaveTrack *right = (WaveTrack *) iter.Next();
         sampleCount rstart;
         sampleCount rlen;

         GetSamples(right, &rstart, &rlen);         

         if (left->GetRate() != right->GetRate()) {
            wxMessageBox(_("Both channels of a stereo track must be the same sample rate."));
            return false;
         }

         if (llen != rlen) {
            wxMessageBox(_("Both channels of a stereo track must be the same length."));
            return false;
         }
      }
      
      left = (WaveTrack *) iter.Next();
   }

   return true;
}
Пример #8
0
bool LadspaEffect::Process()
{
    this->CopyInputWaveTracks(); // Set up mOutputWaveTracks.
    bool bGoodResult = true;

    TrackListIterator iter(mOutputWaveTracks);
    int count = 0;
    Track *left = iter.First();
    Track *right;
    while(left) {
        sampleCount lstart = 0, rstart = 0;
        sampleCount len;
        GetSamples((WaveTrack *)left, &lstart, &len);

        right = NULL;
        if (left->GetLinked() && inputs>1) {
            right = iter.Next();
            GetSamples((WaveTrack *)right, &rstart, &len);
        }

        if (inputs < 2 && right) {
            // If the effect is mono, apply to each channel separately

            bGoodResult = ProcessStereo(count, (WaveTrack *)left, NULL,
                                        lstart, 0, len) &&
                          ProcessStereo(count, (WaveTrack *)right, NULL,
                                        rstart, 0, len);
        }
        else bGoodResult = ProcessStereo(count,
                                             (WaveTrack *)left, (WaveTrack *)right,
                                             lstart, rstart, len);
        if (!bGoodResult)
            break;

        left = iter.Next();
        count++;
    }

    this->ReplaceProcessedWaveTracks(bGoodResult);
    return bGoodResult;
}
Пример #9
0
bool LadspaEffect::Process()
{
   TrackListIterator iter(mWaveTracks);
   int count = 0;
   Track *left = iter.First();
   Track *right;
   while(left) {
      longSampleCount lstart, rstart;
      sampleCount len;
      GetSamples((WaveTrack *)left, &lstart, &len);
      
      right = NULL;
      if (left->GetLinked() && inputs>1) {
         right = iter.Next();         
         GetSamples((WaveTrack *)right, &rstart, &len);
      }

      bool success = false;

      if (inputs < 2 && right) {
         // If the effect is mono, apply to each channel separately

         success = ProcessStereo(count, (WaveTrack *)left, NULL,
                                 lstart, 0, len);
         if (success)
            success = ProcessStereo(count, (WaveTrack *)right, NULL,
                                    rstart, 0, len);
      }
      else success = ProcessStereo(count,
                                   (WaveTrack *)left, (WaveTrack *)right,
                                   lstart, rstart, len);
      if (!success)
         return false;
   
      left = iter.Next();
      count++;
   }

   return true;
}
Пример #10
0
bool LadspaEffect::Init()
{
   mBlockSize = 0;
   mainRate = 0;

   TrackListIterator iter(mWaveTracks);
   VTrack *left = iter.First();
   while(left) {
      sampleCount lstart, rstart, llen, rlen;
      GetSamples((WaveTrack *)left, &lstart, &llen);
      
      if (mainRate == 0)
         mainRate = (int)(((WaveTrack *)left)->GetRate() + 0.5);
      
      if (left->GetLinked()) {
         VTrack *right = iter.Next();
         GetSamples((WaveTrack *)right, &rstart, &rlen);
         
         if (llen != rlen ||
             ((WaveTrack *)left)->GetRate() !=
             ((WaveTrack *)right)->GetRate()) {
            wxMessageBox(_("Sorry, Ladspa Effects cannot be performed "
                           "on stereo tracks where the individual "
                           "channels of the track do not match."));
            return false;
         }
      }
      
      left = iter.Next();
   }

   if (mainRate<=0)
      mainRate = 44100;

   return true;
}
Пример #11
0
bool AllegroSoundSample5::Load( const std::string & path )
{
	if ( m_pInstance )
	{
		al_detach_sample_instance( m_pInstance );
		al_destroy_sample_instance( m_pInstance );
	}

	SamplePtr pSampleData = GetSamples().Load( path );
	if ( !pSampleData || !pSampleData->m_pSample )
		return false;

	m_pInstance = al_create_sample_instance( pSampleData->m_pSample );
	al_attach_sample_instance_to_mixer( m_pInstance,  ((AllegroSound5&)GetSound()).GetSoundMixer() );

	return ( m_pInstance != 0 );
}
Пример #12
0
void TranscriptionToolBar::OnCalibrate(wxCommandEvent & WXUNUSED(event))
{
   //If IO is busy, abort immediately
   if (gAudioIO->IsBusy()){
      SetButton(false,mButtons[TTB_Calibrate]);
      return;
   }


   AudacityProject *p = GetActiveProject();

   TrackList *tl = p->GetTracks();
   TrackListOfKindIterator iter(Track::Wave, tl);
   Track *t = iter.First();   //Get a track

   if(t)
      {
         auto wt = static_cast<const WaveTrack*>(t);
         sampleCount start, len;
         GetSamples(wt, &start, &len);

         mVk->CalibrateNoise(*wt, start, len);
         mVk->AdjustThreshold(3);

         mButtons[TTB_StartOn]->Enable();
         mButtons[TTB_StartOff]->Enable();
         mButtons[TTB_EndOn]->Enable();
         mButtons[TTB_EndOff]->Enable();
         //mThresholdSensitivity->Set(3);

         SetButton(false,mButtons[TTB_Calibrate]);
      }

   mButtons[TTB_StartOn]->Enable();
   mButtons[TTB_StartOff]->Enable();
   mButtons[TTB_EndOn]->Enable();
   mButtons[TTB_EndOff]->Enable();
   mButtons[TTB_SelectSound]->Enable();
   mButtons[TTB_SelectSilence]->Enable();
   mButtons[TTB_AutomateSelection]->Enable();

   //Make the sensititivy slider set the sensitivity by processing an event.
   wxCommandEvent dummy;
   OnSensitivitySlider(dummy);

}
Пример #13
0
bool EffectFilter::Process()
{
   TrackListIterator iter(mWaveTracks);
   VTrack *t = iter.First();
   int count = 0;
   while(t) {
      sampleCount start, len;
      GetSamples((WaveTrack *)t, &start, &len);
      bool success = ProcessOne(count, (WaveTrack *)t, start, len);
      
      if (!success)
         return false;
   
      t = iter.Next();
      count++;
   }
   
   return true;
}
void TranscriptionToolBar::OnSelectSound(wxCommandEvent & WXUNUSED(event))
{

   //If IO is busy, abort immediately
   if (gAudioIO->IsBusy()){
      SetButton(false,mButtons[TTB_SelectSound]);
      return;
   }


   mVk->AdjustThreshold(GetSensitivity());
   AudacityProject *p = GetActiveProject();


   TrackList *tl = p->GetTracks();
   TrackListIterator iter(tl);

   Track *t = iter.First();   //Make a track
   if(t)
      {
         sampleCount start,len;
         GetSamples((WaveTrack*)t, &start,&len);

         //Adjust length to end if selection is null
         //if(len == 0)
         //len = (WaveTrack*)t->GetSequence()->GetNumSamples()-start;

         double rate =  ((WaveTrack*)t)->GetRate();
         sampleCount newstart = mVk->OffBackward(*(WaveTrack*)t,start,start);
         sampleCount newend   = mVk->OffForward(*(WaveTrack*)t,start+len,(int)(tl->GetEndTime()*rate));

         //reset the selection bounds.
         p->SetSel0(newstart / rate);
         p->SetSel1(newend /  rate);
         p->RedrawProject();

      }

   SetButton(false,mButtons[TTB_SelectSound]);
}
Пример #15
0
void TranscriptionToolBar::OnSelectSound(wxCommandEvent & WXUNUSED(event))
{

   //If IO is busy, abort immediately
   if (gAudioIO->IsBusy()){
      SetButton(false,mButtons[TTB_SelectSound]);
      return;
   }


   mVk->AdjustThreshold(GetSensitivity());
   AudacityProject *p = GetActiveProject();


   TrackList *tl = p->GetTracks();
   if(auto wt = *tl->Any<const WaveTrack>().begin()) {
      sampleCount start, len;
      GetSamples(wt, &start, &len);

      //Adjust length to end if selection is null
      //if(len == 0)
      //len = wt->GetSequence()->GetNumSamples()-start;

      double rate =  wt->GetRate();
      auto newstart = mVk->OffBackward(*wt, start, start);
      auto newend   =
      mVk->OffForward(*wt, start + len, (int)(tl->GetEndTime() * rate));

      //reset the selection bounds.
      auto &selectedRegion = p->GetViewInfo().selectedRegion;
      selectedRegion.setTimes(
         newstart.as_double() / rate, newend.as_double() /  rate );
      p->RedrawProject();

   }

   SetButton(false,mButtons[TTB_SelectSound]);
}
Пример #16
0
bool EffectNoiseRemoval::Process()
{
   if (doProfile) {
      for(int i=0; i<windowSize; i++) {
         sum[i] = 0.0;
         sumsq[i] = 0.0;
         profileCount[i] = 0;
      }
   }

   TrackListIterator iter(mWaveTracks);
   VTrack *t = iter.First();
   int count = 0;
   while(t) {
      sampleCount start, len;
      GetSamples((WaveTrack *)t, &start, &len);
      
      bool success = ProcessOne(count, (WaveTrack *)t, start, len);
      
      if (!success)
         return false;
   
      t = iter.Next();
      count++;
   }
   
   if (doProfile) {
      for(int i=0; i<=windowSize/2; i++) {
         float avg = sum[i] / profileCount[i];
         float stddev = sqrt(sumsq[i] - (sum[i]*sum[i])/profileCount[i]) / profileCount[i];

         noiseGate[i] = avg;
      }
      
      hasProfile = true;
   }
   return true;
}
Пример #17
0
bool EffectAmplify::Init()
{
   peak = 0.0;

   TrackListIterator iter(mWaveTracks);
   VTrack *t = iter.First();
   int count = 0;
   while(t) {
      sampleCount start, len;
      sampleType min, max;
      GetSamples((WaveTrack *)t, &start, &len);
      ((WaveTrack *)t)->GetMinMax(start, len, &min, &max);
      float newpeak = (abs(min) > abs(max) ? abs(min) : abs(max)) / 32768.0;
      
      if (newpeak > peak)
         peak = newpeak;
   
      t = iter.Next();
      count++;
   }
   
   return true;

}
Пример #18
0
bool MatrixSystem::LoadData(const QString& matrixFile, const QString& metadataFile)
{
	// parse matrix file
	QFile file(matrixFile);
	if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		Log::Inst().Warning("Unable to open matrix file: " + matrixFile);
		return false;
	}

	QTextStream textStream(&file);	

	QStringList sampleIds;
	bool bHeader = true;
	bool bPhylipFormat = true;
	Matrix matrix;
	while(!textStream.atEnd())
	{
		QString dataRow = textStream.readLine();
		if(dataRow.isEmpty())
			break;

		QStringList dataItems;
		if(dataRow.count(' ') > dataRow.count('\t'))
			dataItems = dataRow.split(' ', QString::SkipEmptyParts);
		else
			dataItems = dataRow.split('\t', QString::SkipEmptyParts);
		if(bHeader)
		{
			bHeader = false;

			// check if this is a Phylip format distance matrix
			if(dataItems.size() == 1)
			{
				bool bNumber;
				int entries = dataItems.at(0).toInt(&bNumber);
				if(bNumber)
				{
					bPhylipFormat = true;
					continue;
				}
			}
		}

		sampleIds.push_back(dataItems.at(0));

		QVector<double> row;
		for(int i = 1; i < dataItems.size(); ++i)
			row.push_back(dataItems.at(i).toDouble());

		matrix.push_back(row);
	}

	// fill in upper triangular data since only the bottom triangular data may have been specified
	m_matrix.clear();
	m_matrix.resize(matrix.size());
	for(int r = 0; r < matrix.size(); ++r)
	{
		m_matrix[r].resize(matrix.size());
		m_matrix[r][r] = 0;

		for(int c = 0; c < r; ++c)
			m_matrix[r][c] = m_matrix[c][r] = matrix[r][c];
	}

	file.close();

	// create samples for matrix file
	GetSamples()->SetSampleByName(sampleIds);

	// parse metadata file
	if(!GetSamples()->GetMetadata()->Load(metadataFile))
	{
		Log::Inst().Error("Unable to parse metadata file.");
		return false;
	}

	return true;
}
Пример #19
0
static void
RasterizeTriangle(const ShadedGrid &sg, int u0, int v0, int u1, int v1,
                  int u2, int v2, Bucket *bucket) 
{
    // Compute offsets in the vertex arrays for the three vertices of the
    // triangle to be rasterized
    int offset0 = sg.nu * v0 + u0;
    int offset1 = sg.nu * v1 + u1;
    int offset2 = sg.nu * v2 + u2;

    // Compute screen-space vertex positions of the triangle at start time;
    Point vx0[2], vx1[2], vx2[2];
    vx0[0].set(sg.x0()[offset0], sg.y0()[offset0], sg.z0()[offset0], sg.w0()[offset0]);
    vx0[1].set(sg.x1()[offset0], sg.y1()[offset0], sg.z1()[offset0], sg.w1()[offset0]);
    vx1[0].set(sg.x0()[offset1], sg.y0()[offset1], sg.z0()[offset1], sg.w0()[offset1]);
    vx1[1].set(sg.x1()[offset1], sg.y1()[offset1], sg.z1()[offset1], sg.w1()[offset1]);
    vx2[0].set(sg.x0()[offset2], sg.y0()[offset2], sg.z0()[offset2], sg.w0()[offset2]);
    vx2[1].set(sg.x1()[offset2], sg.y1()[offset2], sg.z1()[offset2], sg.w1()[offset2]);
    
    // Now compute the bounding box of the triangle on the screen in
    // floating-point pixel coordinates.
    float xMin = vx0[0].x2d(), xMax = vx0[0].x2d(), yMin = vx0[0].y2d(), yMax = vx0[0].y2d();
    for (int i = 0; i < 2; i++)
    {
		xMin = std::min(xMin, std::min(vx0[i].x2d(), std::min(vx1[i].x2d(), vx2[i].x2d())));
		yMin = std::min(yMin, std::min(vx0[i].y2d(), std::min(vx1[i].y2d(), vx2[i].y2d())));
		xMax = std::max(xMax, std::max(vx0[i].x2d(), std::max(vx1[i].x2d(), vx2[i].x2d())));
		yMax = std::max(yMax, std::max(vx0[i].y2d(), std::max(vx1[i].y2d(), vx2[i].y2d())));
    }    

    // Compute integer pixel bounds, clamped to the bucket extent
    int ixMin = std::max((int)floorf(xMin), bucket->x0);
    int ixMax = std::min((int)ceilf(xMax),  bucket->x1);
    int iyMin = std::max((int)floorf(yMin), bucket->y0);
    int iyMax = std::min((int)ceilf(yMax),  bucket->y1);

    // Loop over the bounding box of the pixels that the triangle possibly
    // covers.
    for (int py = iyMin; py < iyMax; ++py) {
        for (int px = ixMin; px < ixMax; ++px) {
            // Get the set of samples for the pixel (px, py)
            float xSamples[MAX_SAMPLES_PER_PIXEL];
            float ySamples[MAX_SAMPLES_PER_PIXEL];
            float timeSamples[MAX_SAMPLES_PER_PIXEL];
            GetSamples(px, py, bucket->kSamplesPerPixel, xSamples, ySamples,
                       timeSamples);

            // Now loop over all of the samples for the pixel and see if
            // each one is inside the triangle.
            for (int sampleNum = 0; sampleNum < bucket->kSamplesPerPixel;
                 ++sampleNum) {
                // Evaluate edge equations at sample position (sx,sy).
                float sx = xSamples[sampleNum], sy = ySamples[sampleNum];
				float st = timeSamples[sampleNum];
				// find the triangle at the time st
		
			    // Triangle setup.
			    // Compute the edge equation coefficients.
				float X0, X1, X2, Y0, Y1, Y2, Z0, Z1, Z2;
				Point vt0 = vx0[0] * (1 - st) + vx0[1] * st;
				Point vt1 = vx1[0] * (1 - st) + vx1[1] * st;
				Point vt2 = vx2[0] * (1 - st) + vx2[1] * st;
				X0 = vt0.x2d(); Y0 = vt0.y2d();
				X1 = vt1.x2d(); Y1 = vt1.y2d();
				X2 = vt2.x2d(); Y2 = vt2.y2d();
				Z0 = vt0.z; Z1 = vt1.z; Z2 = vt2.z;
		
			    float edge_a_0 = -(Y1 - Y0);
			    float edge_a_1 = -(Y2 - Y1);
			    float edge_a_2 = -(Y0 - Y2);

			 	float edge_b_0 =   X1 - X0;
			    float edge_b_1 =   X2 - X1;
			    float edge_b_2 =   X0 - X2;

			    float edge_c_0 = edge_a_0 * -X0 + edge_b_0 * -Y0;
			    float edge_c_1 = edge_a_1 * -X1 + edge_b_1 * -Y1;
			    float edge_c_2 = edge_a_2 * -X2 + edge_b_2 * -Y2;

			    // Triangle area and inverse area
			    float area = 0.5f * ((X1 - X0) * (Y2 - Y0) - (Y1 - Y0) * (X2 - X0));
			    float inv2Area = 1.f / (2.f * area);
				if (area <= .0)
					continue;
		
		        float e0 = edge_a_0 * sx + edge_b_0 * sy + edge_c_0;
		        float e1 = edge_a_1 * sx + edge_b_1 * sy + edge_c_1;
		        float e2 = edge_a_2 * sx + edge_b_2 * sy + edge_c_2;

		        if (e0 <= 0.f || e1 <= 0.f || e2 <= 0.f)
		            // The sample is outside the triangle
		            continue;

                // Compute interpolation weights
                float wt0 = e1 * inv2Area;
                float wt1 = e2 * inv2Area;
                float wt2 = e0 * inv2Area;

                // Interpolate z
                float z = (wt0 * Z0 +
                           wt1 * Z1 +
                           wt2 * Z2);

                // Z-test: is the z value closer than the z value currently
                // in the framebuffer?
                if (z < *bucket->Z(px, py, sampleNum)) {
                    // z-test passed; update z in bucket framebuffer
                    *bucket->Z(px, py, sampleNum) = z;

                    // Interpolate R, G, B
                    float r = (wt0 * sg.r()[offset0] +
                               wt1 * sg.r()[offset1] +
                               wt2 * sg.r()[offset2]);
                    float g = (wt0 * sg.g()[offset0] +
                               wt1 * sg.g()[offset1] +
                               wt2 * sg.g()[offset2]);
                    float b = (wt0 * sg.b()[offset0] +
                               wt1 * sg.b()[offset1] +
                               wt2 * sg.b()[offset2]);

                    // Store r, g, b in framebuffer
                    *bucket->R(px, py, sampleNum) = r;
                    *bucket->G(px, py, sampleNum) = g;
                    *bucket->B(px, py, sampleNum) = b;
                }
            }
        }
    }
}
Пример #20
0
void Mixer::MixSameRate(int *channelFlags, WaveTrack * src,
                        double t0, double t1)
{
   if ((t0 - src->GetOffset()) >= src->GetNumSamples() / src->GetRate() ||
       (t1 - src->GetOffset()) <= 0)
      return;
      
   int s0 = int ((t0 - src->GetOffset()) * src->GetRate() + 0.5);
   int s1 = int ((t1 - src->GetOffset()) * src->GetRate() + 0.5);

   int slen = s1 - s0;

   if (slen <= 0)
      return;
   if (slen > mBufferSize)
      slen = mBufferSize;

   GetSamples(src, s0, slen);

   double volume;
   if (mUseVolumeSlider)
      volume = mControlToolBar->GetSoundVol();
   else
      volume = 1.0;

   Envelope *e = src->GetEnvelope();

   e->GetValues(mEnvValues, slen, t0, 1.0 / mRate);

   // Mix it down to the appropriate tracks

   for (int c = 0; c < mNumChannels; c++) {
      if (!channelFlags[c])
         continue;

      samplePtr destPtr;
      int skip;

      if (mInterleaved) {
         destPtr = mBuffer[0] + c*SAMPLE_SIZE(mFormat);
         skip = mNumChannels;
      } else {
         destPtr = mBuffer[c];
         skip = 1;
      }

      // This is the mixing inner loop, which we want
      // as optimized as possible

      switch(mFormat) {
      case int16Sample: {
         short *dest = (short *)destPtr;
         short *temp = (short *)mTemp;
         for (int j = 0; j < slen; j++) {
            *dest += (short)rint(temp[j] * volume * mEnvValues[j]);
            dest += skip;
         }
      } break;
      case int24Sample: {
         int *dest = (int *)destPtr;
         int *temp = (int *)mTemp;
         for (int j = 0; j < slen; j++) {
            *dest += (int)rint(temp[j] * volume * mEnvValues[j]);
            dest += skip;
         }
      } break;
      case floatSample: {
         float *dest = (float *)destPtr;
         float *temp = (float *)mTemp;
         for (int j = 0; j < slen; j++) {
            *dest += temp[j] * volume * mEnvValues[j];
            dest += skip;
         }
      } break;
      } // switch
   }
}
Пример #21
0
void Mixer::MixDiffRates(int *channelFlags, WaveTrack * src,
                         double t0, double t1)
{
   if ((t0 - src->GetOffset()) >= src->GetNumSamples() / src->GetRate() ||
       (t1 - src->GetOffset()) <= 0)
      return;

   int s0 = int ((t0 - src->GetOffset()) * src->GetRate());

   // get a couple more samples than we need
   int slen = int ((t1 - t0) * src->GetRate()) + 2;

   int destlen = int ((t1 - t0) * mRate + 0.5);

   GetSamples(src, s0, slen);

   double volume;
   if (mUseVolumeSlider)
      volume = mControlToolBar->GetSoundVol();
   else
      volume = 1.0;

   Envelope *e = src->GetEnvelope();

   e->GetValues(mEnvValues, mBufferSize, t0, 1.0 / mRate);

   // Mix it down to the appropriate tracks

   for (int c = 0; c < mNumChannels; c++) {
      if (!channelFlags[c])
         continue;

      samplePtr destPtr;
      int skip;

      if (mInterleaved) {
         destPtr = mBuffer[0] + c*SAMPLE_SIZE(mFormat);
         skip = mNumChannels;
      } else {
         destPtr = mBuffer[c];
         skip = 1;
      }

      // This is the mixing inner loop, which we want
      // as optimized as possible

      int i = 0;
      switch(mFormat) {
      case int16Sample: {
         short *temp = (short *)mTemp;
         short *dest = (short *)destPtr;
         int frac = int(32768.0 * (t0 - s0/src->GetRate()));
         int fracstep = int(32768.0 * src->GetRate()/mRate + 0.5);

         for (int j = 0; j < destlen; j++) {
            short value = (temp[i]*(32768-frac) + temp[i+1]*frac) >> 15;
            frac += fracstep;
            i += (frac >> 15);      // frac/32768
            frac = (frac & 0x7FFF); // frac%32768
            
            *dest += short(value * volume * mEnvValues[j] + 0.5);
            dest += skip;
         }
      } break;
      case int24Sample: {
         int *temp = (int *)mTemp;
         int *dest = (int *)destPtr;
         float frac = t0 - s0/src->GetRate();
         float fracstep = src->GetRate()/mRate;

         for (int j = 0; j < destlen; j++) {
            float value = (temp[i]*(1.0-frac) + temp[i+1]*frac);
            frac += fracstep;
            int integerPart = (int)frac;
            i += integerPart;
            frac -= (float)integerPart;
            
            *dest += int(value * volume * mEnvValues[j] + 0.5);
            dest += skip;
         }
      } break;
      case floatSample: {
         float *temp = (float *)mTemp;
         float *dest = (float *)destPtr;
         float frac = t0 - s0/src->GetRate();
         float fracstep = src->GetRate()/mRate;

         for (int j = 0; j < destlen; j++) {
            float value = temp[i]*(1.0-frac) + temp[i+1]*frac;
            frac += fracstep;
            int integerPart = (int)frac;
            i += integerPart;
            frac -= (float)integerPart;
            
            *dest += value * volume * mEnvValues[j];
            dest += skip;
         }
      } break;
      } // switch

   }
}
Пример #22
0
bool VampEffect::Process()
{
   if (!mPlugin) return false;

   TrackListIterator iter(mWaveTracks);

   int count = 0;

   WaveTrack *left = (WaveTrack *)iter.First();

   bool multiple = false;
   int prevTrackChannels = 0;

   TrackListIterator scooter(iter);
   if (left->GetLinked()) scooter.Next();      
   if (scooter.Next()) {
      // if there is another track beyond this one and any linked one,
      // then we're processing more than one track.  That means we
      // should use the originating track name in each new label
      // track's name, to make clear which is which
      multiple = true;
   }

   while (left) {

      sampleCount lstart, rstart;
      sampleCount len;
      GetSamples(left, &lstart, &len);
      
      WaveTrack *right = NULL;
      int channels = 1;

      if (left->GetLinked()) {
         right = (WaveTrack *)iter.Next();
         channels = 2;
         GetSamples(right, &rstart, &len);
      }

      size_t step = mPlugin->getPreferredStepSize();
      size_t block = mPlugin->getPreferredBlockSize();

      bool initialiseRequired = true;

      if (block == 0) {
         if (step != 0) block = step;
         else block = 1024;
      }
      if (step == 0) {
         step = block;
      }

      if (prevTrackChannels > 0) {
         // Plugin has already been initialised, so if the number of
         // channels remains the same, we only need to do a reset.
         // Otherwise we need to re-construct the whole plugin,
         // because a Vamp plugin can't be re-initialised.
         if (prevTrackChannels == channels) {
            mPlugin->reset();
            initialiseRequired = false;
         } else {
            //!!! todo: retain parameters previously set
            Init();
         }
      }

      if (initialiseRequired) {
         if (!mPlugin->initialise(channels, step, block)) {
            wxMessageBox(_("Sorry, Vamp Plug-in failed to initialize."));
            return false;
         }
      }

      LabelTrack *ltrack = mFactory->NewLabelTrack();

      if (!multiple) {
         ltrack->SetName(GetEffectName());
      } else {
         ltrack->SetName(wxString::Format(wxT("%s: %s"),
                                          left->GetName().c_str(),
                                          GetEffectName().c_str()));
      }

      mTracks->Add(ltrack);

      float **data = new float*[channels];
      for (int c = 0; c < channels; ++c) data[c] = new float[block];

      sampleCount originalLen = len;
      sampleCount ls = lstart;
      sampleCount rs = rstart;

      while (len) {
         
         int request = block;
         if (request > len) request = len;

         if (left) left->Get((samplePtr)data[0], floatSample, ls, request);
         if (right) right->Get((samplePtr)data[1], floatSample, rs, request);

         if (request < (int)block) {
            for (int c = 0; c < channels; ++c) {
               for (int i = request; i < (int)block; ++i) {
                  data[c][i] = 0.f;
               }
            }
         }

         Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime
            (ls, (int)(mRate + 0.5));

         Vamp::Plugin::FeatureSet features = mPlugin->process(data, timestamp);
         AddFeatures(ltrack, features);

         if (len > (int)step) len -= step;
         else len = 0;

         ls += step;
         rs += step;

         if (channels > 1) {
            if (TrackGroupProgress(count, (ls - lstart) / double(originalLen)))
               return false;
         } else {
            if (TrackProgress(count, (ls - lstart) / double(originalLen)))
               return false;
         }
      }

      Vamp::Plugin::FeatureSet features = mPlugin->getRemainingFeatures();
      AddFeatures(ltrack, features);

      prevTrackChannels = channels;

      left = (WaveTrack *)iter.Next();
   }

   return true;
}
void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event))
{


   //If IO is busy, abort immediately
   if (gAudioIO->IsBusy())
   {
      SetButton(false,mButtons[TTB_EndOff]);
      return;
   }

   wxBusyCursor busy;

   mVk->AdjustThreshold(GetSensitivity());
   AudacityProject *p = GetActiveProject();
   TrackList *tl = p->GetTracks();
   TrackListIterator iter(tl);

   Track *t = iter.First();   //Make a track
   if(t)
      {
         sampleCount start,len;
         GetSamples((WaveTrack*)t, &start,&len);

         //Adjust length to end if selection is null
         if(len == 0)
            {
               len = start;
               start = 0;
            }
         int lastlen = 0;
         sampleCount newStart, newEnd;
         double newStartPos, newEndPos;


         //This is the minumum word size in samples (.05 is 50 ms)
         int minWordSize = (int)(((WaveTrack*)t)->GetRate() * .05);

         //Continue until we have processed the entire
         //region, or we are making no progress.
         while(len > 0 && lastlen != len)
            {

               lastlen = len;

               newStart = mVk->OnForward(*(WaveTrack*)t,start,len);

               //JKC: If no start found then don't add any labels.
               if( newStart==start)
                  break;

               //Adjust len by the NEW start position
               len -= (newStart - start);

               //Adjust len by the minimum word size
               len -= minWordSize;



               //OK, now we have found a NEW starting point.  A 'word' should be at least
               //50 ms long, so jump ahead minWordSize

               newEnd   = mVk->OffForward(*(WaveTrack*)t,newStart+minWordSize, len);

               //If newEnd didn't move, we should give up, because
               // there isn't another end before the end of the selection.
               if(newEnd == (newStart + minWordSize))
                  break;


               //Adjust len by the NEW word end
               len -= (newEnd - newStart);

               //Calculate the start and end of the words, in seconds
               newStartPos = newStart / ((WaveTrack*)t)->GetRate();
               newEndPos = newEnd / ((WaveTrack*)t)->GetRate();


               //Increment
               start = newEnd;

               p->DoAddLabel(SelectedRegion(newStartPos, newEndPos));
               p->RedrawProject();
            }
         SetButton(false, mButtons[TTB_AutomateSelection]);
      }
}
Пример #24
0
bool VampEffect::Process()
{
   if (!mPlugin)
   {
      return false;
   }

   int count = 0;

   bool multiple = false;
   unsigned prevTrackChannels = 0;

   if (GetNumWaveGroups() > 1)
   {
      // if there is another track beyond this one and any linked one,
      // then we're processing more than one track.  That means we
      // should use the originating track name in each NEW label
      // track's name, to make clear which is which
      multiple = true;
   }

   std::vector<std::shared_ptr<Effect::AddedAnalysisTrack>> addedTracks;

   for (auto leader : inputTracks()->Leaders<const WaveTrack>())
   {
      auto channelGroup = TrackList::Channels(leader);
      auto left = *channelGroup.first++;

      sampleCount lstart, rstart = 0;
      sampleCount len;
      GetSamples(left, &lstart, &len);

      unsigned channels = 1;

      // channelGroup now contains all but the first channel
      const WaveTrack *right =
         channelGroup.size() ? *channelGroup.first++ : nullptr;
      if (right)
      {
         channels = 2;
         GetSamples(right, &rstart, &len);
      }

      // TODO: more-than-two-channels

      size_t step = mPlugin->getPreferredStepSize();
      size_t block = mPlugin->getPreferredBlockSize();

      bool initialiseRequired = true;

      if (block == 0)
      {
         if (step != 0)
         {
            block = step;
         }
         else
         {
            block = 1024;
         }
      }

      if (step == 0)
      {
         step = block;
      }

      if (prevTrackChannels > 0)
      {
         // Plugin has already been initialised, so if the number of
         // channels remains the same, we only need to do a reset.
         // Otherwise we need to re-construct the whole plugin,
         // because a Vamp plugin can't be re-initialised.
         if (prevTrackChannels == channels)
         {
            mPlugin->reset();
            initialiseRequired = false;
         }
         else
         {
            //!!! todo: retain parameters previously set
            Init();
         }
      }

      if (initialiseRequired)
      {
         if (!mPlugin->initialise(channels, step, block))
         {
            Effect::MessageBox(_("Sorry, Vamp Plug-in failed to initialize."));
            return false;
         }
      }

      const auto effectName = GetSymbol().Translation();
      addedTracks.push_back(AddAnalysisTrack(
         multiple
         ? wxString::Format( _("%s: %s"), left->GetName(), effectName )
         : effectName
      ));
      LabelTrack *ltrack = addedTracks.back()->get();

      FloatBuffers data{ channels, block };

      auto originalLen = len;
      auto ls = lstart;
      auto rs = rstart;

      while (len != 0)
      {
         const auto request = limitSampleBufferSize( block, len );

         if (left)
         {
            left->Get((samplePtr)data[0].get(), floatSample, ls, request);
         }

         if (right)
         {
            right->Get((samplePtr)data[1].get(), floatSample, rs, request);
         }

         if (request < block)
         {
            for (unsigned int c = 0; c < channels; ++c)
            {
               for (decltype(block) i = request; i < block; ++i)
               {
                  data[c][i] = 0.f;
               }
            }
         }

         // UNSAFE_SAMPLE_COUNT_TRUNCATION
         // Truncation in case of very long tracks!
         Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime(
            long( ls.as_long_long() ),
            (int)(mRate + 0.5)
         );

         Vamp::Plugin::FeatureSet features = mPlugin->process(
            reinterpret_cast< float** >( data.get() ), timestamp);
         AddFeatures(ltrack, features);

         if (len > (int)step)
         {
            len -= step;
         }
         else
         {
            len = 0;
         }

         ls += step;
         rs += step;

         if (channels > 1)
         {
            if (TrackGroupProgress(count,
                  (ls - lstart).as_double() /
                  originalLen.as_double() ))
            {
               return false;
            }
         }
         else
         {
            if (TrackProgress(count,
                  (ls - lstart).as_double() /
                  originalLen.as_double() ))
            {
               return false;
            }
         }
      }

      Vamp::Plugin::FeatureSet features = mPlugin->getRemainingFeatures();
      AddFeatures(ltrack, features);

      prevTrackChannels = channels;
   }

   // All completed without cancellation, so commit the addition of tracks now
   for (auto &addedTrack : addedTracks)
      addedTrack->Commit();

   return true;
}
Пример #25
0
bool VSTEffect::Process()
{
   CopyInputTracks();
   bool bGoodResult = true;

   mInBuffer = NULL;
   mOutBuffer = NULL;

   TrackListIterator iter(mOutputTracks);
   int count = 0;
   bool clear = false;
   WaveTrack *left = (WaveTrack *) iter.First();
   while (left) {
      WaveTrack *right;
      sampleCount len;
      sampleCount lstart;
      sampleCount rstart;

      GetSamples(left, &lstart, &len);

      mChannels = 1;

      right = NULL;
      rstart = 0;
      if (left->GetLinked() && mInputs > 1) {
         right = (WaveTrack *) iter.Next();         
         GetSamples(right, &rstart, &len);
         clear = false;
         mChannels = 2;
      }

      if (mBlockSize == 0) {
         mBlockSize = left->GetMaxBlockSize() * 2;

         // Some VST effects (Antress Modern is an example), do not like
         // overly large block sizes.  Unfortunately, I have not found a
         // way to determine if the effect has a maximum it will support,
         // so just limit to small value for now.  This will increase
         // processing time and, it's a shame, because most plugins seem
         // to be able to handle much larger sizes.
         if (mBlockSize > 8192) { // The Antress limit
            mBlockSize = 8192;
         }

         mInBuffer = new float *[mInputs];
         for (int i = 0; i < mInputs; i++) {
            mInBuffer[i] = new float[mBlockSize];
         }

         mOutBuffer = new float *[mOutputs];
         for (int i = 0; i < mOutputs; i++) {
            mOutBuffer[i] = new float[mBlockSize];
         }

         // Turn the power off
         callDispatcher(effMainsChanged, 0, 0, NULL, 0.0);

         // Set processing parameters
         callDispatcher(effSetSampleRate, 0, 0, NULL, left->GetRate());
         callDispatcher(effSetBlockSize, 0, mBlockSize, NULL, 0.0);
      }

      // Clear unused input buffers
      if (!right && !clear) {
         for (int i = 1; i < mInputs; i++) {
            for (int j = 0; j < mBlockSize; j++) {
               mInBuffer[i][j] = 0.0;
            }
         }
         clear = true;
      }

      bGoodResult = ProcessStereo(count, left, right, lstart, rstart, len);
      if (!bGoodResult) {
         break;
      }

      left = (WaveTrack *) iter.Next();
      count++;
   }

   if (mOutBuffer) {
      for (int i = 0; i < mOutputs; i++) {
         delete mOutBuffer[i];
      }
      delete [] mOutBuffer;
      mOutBuffer = NULL;
   }

   if (mInBuffer) {
      for (int i = 0; i < mInputs; i++) {
         delete mInBuffer[i];
      }
      delete [] mInBuffer;
      mInBuffer = NULL;
   }

   ReplaceProcessedTracks(bGoodResult); 
   return bGoodResult;
}