Beispiel #1
0
int samplerate(jack_nframes_t rate, void *arg)
{
  JackCard* obj = (JackCard*) arg;
  int error;

  obj->rate = rate;
  if (obj->read.open) {
    obj->read.data.src_ratio = (double)obj->read.rate / (double)obj->rate;
    obj->read.data.input_frames = (long)((double)obj->read.frames/obj->read.data.src_ratio);
    g_free(obj->read.data.data_in);
    obj->read.data.data_in = malloc(obj->read.data.input_frames*sizeof(float));
    if (obj->read.src_state)
      if ((error = src_set_ratio(obj->read.src_state, obj->read.data.src_ratio)) != 0)
	g_warning("Error while resetting the write samplerate: %s", src_strerror(error));
  }
  if (obj->write.open) {
    obj->write.data.src_ratio = (double)obj->rate / (double)obj->write.rate;
    obj->write.data.output_frames = (long)((double)obj->write.frames*obj->write.data.src_ratio);
    g_free(obj->write.data.data_out);
    obj->write.data.data_out = malloc(obj->write.data.output_frames*sizeof(float));
    if (obj->write.src_state) 
      if ((error = src_set_ratio(obj->write.src_state, obj->write.data.src_ratio)) != 0)
	g_warning("Error while resetting the write samplerate: %s", src_strerror(error));
  }
  return 0;
}
Beispiel #2
0
int Resample::Process(double  factor,
                      float  *inBuffer,
                      int     inBufferLen,
                      bool    lastFlag,
                      int    *inBufferUsed,
                      float  *outBuffer,
                      int     outBufferLen)
{
   if (mInitial) {
      src_set_ratio((SRC_STATE *)mHandle, factor);
      mInitial = false;
   }

   SRC_DATA data;

   data.data_in = inBuffer;
   data.data_out = outBuffer;
   data.input_frames = inBufferLen;
   data.output_frames = outBufferLen;
   data.input_frames_used = 0;
   data.output_frames_gen = 0;
   data.end_of_input = (int)lastFlag;
   data.src_ratio = factor;

   int err = src_process((SRC_STATE *)mHandle, &data);
   if (err) {
      wxFprintf(stderr, _("Libsamplerate error: %d\n"), err);
      return 0;
   }

   *inBufferUsed = (int)data.input_frames_used;
   return (int)data.output_frames_gen;
}
Beispiel #3
0
void
ddb_src_set_ratio (ddb_dsp_context_t *_src, float ratio) {
    ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
    if (src->srcdata.src_ratio != ratio) {
        src->srcdata.src_ratio = ratio;
        src_set_ratio (src->src, ratio);
    }
}
void* decOpen(
	const char* inputurl,
	size_t* bitspersample,
	size_t* channels,
	size_t* samplerate)
{
	int i;

	for(i = 0; decoders[i].open != NULL ; i++)
	{
		int err;
		void* data;
		dec_data* ret;

		if((data = decoders[i].open(
			inputurl,
			bitspersample, 
			channels,
			samplerate,
			&err)) == NULL)
		{
			if(err != INVALID_FORMAT)
				return NULL;
			else
				continue;
		}
 	
		if((ret = (dec_data*)malloc(sizeof(dec_data))) == NULL)
		{
			decoders[i].close(data);
			return NULL;
		}

		ret->decoder = &decoders[i];
		ret->data    = data;
	
		if((ret->converter = src_new(SRC_LINEAR, audio_channels, &err)) == NULL)
		{
			LOG(L"libsamplerate: " MB_FORMAT "\n", src_strerror(err));
	
			decoders[i].close(data);
			free(ret);
			
			return NULL;
		}
		
		ret->ratio = ((double)audio_samplerate / (double)*samplerate);
		src_set_ratio((SRC_STATE*)ret->converter, ret->ratio);
		
		ret->samplerate = *samplerate;
		ret->channels   = *channels;
		
		return ret;
	}

	return NULL;
}
Beispiel #5
0
void SampleChannel::setPitch(float v)
{
	pitch = v;
	rsmp_data.src_ratio = 1/pitch;

	/* if status is off don't slide between frequencies */

	if (status & (STATUS_OFF | STATUS_WAIT))
		src_set_ratio(rsmp_state, 1/pitch);
}
Beispiel #6
0
static block_t *Resample (filter_t *filter, block_t *in)
{
    block_t *out = NULL;
    const size_t framesize = filter->fmt_out.audio.i_bytes_per_frame;

    SRC_STATE *s = (SRC_STATE *)filter->p_sys;
    SRC_DATA src;

    src.src_ratio = (double)filter->fmt_out.audio.i_rate
                  / (double)filter->fmt_in.audio.i_rate;

    int err = src_set_ratio (s, src.src_ratio);
    if (err != 0)
    {
        msg_Err (filter, "cannot update resampling ratio: %s",
                 src_strerror (err));
        goto error;
    }

    src.input_frames = in->i_nb_samples;
    src.output_frames = ceil (src.src_ratio * src.input_frames);
    src.end_of_input = 0;

    out = block_Alloc (src.output_frames * framesize);
    if (unlikely(out == NULL))
        goto error;

    src.data_in = (float *)in->p_buffer;
    src.data_out = (float *)out->p_buffer;

    err = src_process (s, &src);
    if (err != 0)
    {
        msg_Err (filter, "cannot resample: %s", src_strerror (err));
        block_Release (out);
        out = NULL;
        goto error;
    }

    if (src.input_frames_used < src.input_frames)
        msg_Err (filter, "lost %ld of %ld input frames",
                 src.input_frames - src.input_frames_used, src.input_frames);

    out->i_buffer = src.output_frames_gen * framesize;
    out->i_nb_samples = src.output_frames_gen;
    out->i_pts = in->i_pts;
    out->i_length = src.output_frames_gen * CLOCK_FREQ
                  / filter->fmt_out.audio.i_rate;
error:
    block_Release (in);
    return out;
}
Beispiel #7
0
int ResampleSRC::Do(int chns,Fifo<float> *input,float *const *output,int need,double ratio)
{
    if(ratio == 1) 
        return Resample::Do(chns,input,output,frames,1);

    assert(chns <= channels);
    
    SRC_DATA src_data;
	src_data.src_ratio = ratio;
	src_data.end_of_input = 0;

    int count = -1;

	// hopefully all channel fifos advance uniformly.....
	for(int i = 0; i < chns; ++i) {
		src_set_ratio(state[i],ratio);

		for(int got = 0; got < frames; ) {
			src_data.data_out = output[i]+got;
			src_data.output_frames = frames-got;

			if(decoded[i].Have()) {
				src_data.data_in = input[i].ReadPtr();
				src_data.input_frames = input[i].ReadSamples();

				int err = src_process(state[i],&src_data);
				if(err) post("src_process error %i",err);

				// advance buffer
				decoded[i].Read(src_data.input_frames_used,NULL);
			}
			else {
				schedWait();
				if(debug) post("fifo underrun");

				// Buffer underrun!! -> zero output buffer
				memset(src_data.data_out,0,src_data.output_frames*sizeof(*src_data.data_out));
				src_data.output_frames_gen = src_data.output_frames;
			}
			got += src_data.output_frames_gen;
		}

        assert(count < 0 || got == count);
        count = got;
	}

    return count;
}
Beispiel #8
0
   int VarRateResample::Process(double  factor,
                                  float  *inBuffer,
                                  int     inBufferLen,
                                  bool    lastFlag,
                                  int    *inBufferUsed,
                                  float  *outBuffer,
                                  int     outBufferLen)
   {
      src_set_ratio((SRC_STATE *)mHandle, factor);

      SRC_DATA data;
      
      if(mShouldReset) {
         if(inBufferLen > mSamplesLeft) {
            mShouldReset = false;
            src_reset((SRC_STATE *)mHandle);
         } else {
            mSamplesLeft -= inBufferLen;
         }
      }

      data.data_in = inBuffer;
      data.data_out = outBuffer;
      data.input_frames = inBufferLen;
      data.output_frames = outBufferLen;
      data.input_frames_used = 0;
      data.output_frames_gen = 0;
      data.end_of_input = (int)lastFlag;
      data.src_ratio = factor;

      int err = src_process((SRC_STATE *)mHandle, &data);
      if (err) {
         wxFprintf(stderr, _("Libsamplerate error: %d\n"), err);
         return 0;
      }
      
      if(lastFlag) {
         mShouldReset = true;
         mSamplesLeft = inBufferLen - (int)data.input_frames_used;
      }

      *inBufferUsed = (int)data.input_frames_used;
      return (int)data.output_frames_gen;
   }
void CDVDPlayerResampler::Add(DVDAudioFrame &audioframe, double pts)
{
  //check if nr of channels changed so we can allocate new buffers if necessary
  CheckResampleBuffers(audioframe.channel_count);

  //value to divide samples by to get them into -1.0:1.0 range
  float scale = (float)(1 << (audioframe.bits_per_sample - 1));
  int   nrframes = audioframe.size / audioframe.channel_count / (audioframe.bits_per_sample / 8);

  //resize sample buffer if necessary
  //we want the buffer to be large enough to hold the current frames in it,
  //the number of frames needed for libsamplerate's input
  //and the maximum number of frames libsamplerate might generate, times 2 for safety
  ResizeSampleBuffer(m_bufferfill + nrframes + nrframes * MathUtils::round_int(m_ratio + 0.5) * 2);

  //assign samplebuffers
  m_converterdata.input_frames = nrframes;
  m_converterdata.output_frames = m_buffersize - m_bufferfill - m_converterdata.input_frames;
  //output buffer starts at the place where the buffer doesn't hold samples
  m_converterdata.data_out = m_buffer + m_bufferfill * m_nrchannels;
  //intput buffer is a block of data at the end of the buffer
  m_converterdata.data_in = m_converterdata.data_out + m_converterdata.output_frames * m_nrchannels;

  //add samples to the resample input buffer
  int16_t* inputptr  = (int16_t*)audioframe.data;
  float*   outputptr = m_converterdata.data_in;

  for (int i = 0; i < nrframes * m_nrchannels; i++)
    *outputptr++ = (float)*inputptr++ / scale;

  //resample
  m_converterdata.src_ratio = m_ratio;
  src_set_ratio(m_converter, m_ratio);
  src_process(m_converter, &m_converterdata);

  //calculate a pts for each sample
  for (int i = 0; i < m_converterdata.output_frames_gen; i++)
  {
    m_ptsbuffer[m_bufferfill] = pts + i * (audioframe.duration / (double)m_converterdata.output_frames_gen);
    m_bufferfill++;
  }
}
static bool
pcm_resample_set(struct pcm_resample_state *state,
		 uint8_t channels, unsigned src_rate, unsigned dest_rate,
		 GError **error_r)
{
	static int convalgo = -1;
	int error;
	SRC_DATA *data = &state->data;

	if (convalgo < 0)
		convalgo = pcm_resample_get_converter();

	/* (re)set the state/ratio if the in or out format changed */
	if (channels == state->prev.channels &&
	    src_rate == state->prev.src_rate &&
	    dest_rate == state->prev.dest_rate)
		return true;

	state->error = 0;
	state->prev.channels = channels;
	state->prev.src_rate = src_rate;
	state->prev.dest_rate = dest_rate;

	if (state->state)
		state->state = src_delete(state->state);

	state->state = src_new(convalgo, channels, &error);
	if (!state->state) {
		g_set_error(error_r, libsamplerate_quark(), state->error,
			    "libsamplerate initialization has failed: %s",
			    src_strerror(error));
		return false;
	}

	data->src_ratio = (double)dest_rate / (double)src_rate;
	g_debug("setting samplerate conversion ratio to %.2lf",
		data->src_ratio);
	src_set_ratio(state->state, data->src_ratio);

	return true;
}
Beispiel #11
0
int JackProcess(jack_nframes_t nframes, void *arg)
{
  DevJack *dev=(DevJack *)arg;
  static unsigned i;
  static jack_nframes_t j;
  static float pcm_s1[MAX_AUDIO_CHANNELS*RINGBUFFER_SIZE];
  static float pcm_s2[MAX_AUDIO_CHANNELS*RINGBUFFER_SIZE];
  static unsigned ring_frames;
  static unsigned n;
  static int err;
  static unsigned pcm_start=0;
  static int pcm_offset=0;
  static float lvls[MAX_AUDIO_CHANNELS];

  //
  // Wait for PCM Buffer to Fill
  //
  if(!dev->jack_started) {
    if(dev->codec()->ring()->readSpace()<2*dev->codec()->samplerate()) {
      return 0;
    }
    dev->jack_pll_setpoint_frames=2*dev->codec()->samplerate();
    dev->jack_started=true;
  }

  //
  // Update PLL
  //
  ring_frames=dev->codec()->ring()->readSpace();
  if(ring_frames>dev->jack_pll_setpoint_frames) {
    if(dev->jack_pll_offset>(-PLL_CORRECTION_LIMIT)) {
      dev->jack_pll_offset-=PLL_CORRECTION;
    }
  }
  else {
    if(dev->jack_pll_offset<(PLL_CORRECTION_LIMIT)) {
      dev->jack_pll_offset+=PLL_CORRECTION;
    }
  }
  dev->jack_data.src_ratio=dev->jack_pll_setpoint_ratio+dev->jack_pll_offset;
  src_set_ratio(dev->jack_src,dev->jack_data.src_ratio);

  //
  // Get Buffers
  //
  for(i=0;i<dev->codec()->channels();i++) {
    jack_cb_buffers[i]=(jack_default_audio_sample_t *)
      jack_port_get_buffer(dev->jack_jack_ports[i],nframes);
  }

  //
  // Read Codec Output
  //
  n=nframes/dev->jack_data.src_ratio+pcm_offset;
  if(dev->codec()->ring()->readSpace()>=n) {
    n=dev->codec()->ring()->read(pcm_s1,n);
    //
    // SRC
    //
    dev->jack_data.data_in=pcm_s1;
    dev->jack_data.input_frames=n;
    dev->jack_data.data_out=pcm_s2+pcm_start*dev->codec()->channels();
    dev->jack_data.output_frames=
      MAX_AUDIO_CHANNELS*RINGBUFFER_SIZE/dev->codec()->channels()-pcm_start;
    dev->jack_play_position+=n;
    if((err=src_process(dev->jack_src,&dev->jack_data))<0) {
      fprintf(stderr,"SRC processing error [%s]\n",src_strerror(err));
      exit(GLASS_EXIT_SRC_ERROR);
    }
    n=dev->jack_data.output_frames_gen+pcm_start;

    //
    // De-interleave Channels and Write to Jack Buffers
    //
    for(i=0;i<dev->codec()->channels();i++) {
      if(jack_cb_buffers[i]!=NULL) {
	for(j=0;j<nframes;j++) {
	  jack_cb_buffers[i][j]=pcm_s2[dev->codec()->channels()*j+i];
	}
      }
    }

    //
    // Update Meters
    //
    dev->peakLevels(lvls,pcm_s2,nframes,dev->codec()->channels());
    for(i=0;i<dev->codec()->channels();i++) {
      dev->jack_meter_avg[i]->addValue(lvls[i]);
    }
    dev->setMeterLevels(lvls);

    //
    // Move left-overs to start of buffer
    //
    if(n>nframes) {
      pcm_start=n-nframes;
      for(i=0;i<pcm_start;i++) {
	for(j=0;j<dev->codec()->channels();j++) {
	  pcm_s2[dev->codec()->channels()*i+j]=
	    pcm_s2[(nframes+i)*dev->codec()->channels()+j];
	}
      }
    }
    else {
      pcm_start=0;
    }
    if(pcm_start<2) {
      pcm_offset=1;
    }
    else {
      pcm_offset=0;
    }
  }

  return 0;
}
Beispiel #12
0
/*! Get sample frames
	\param buf		pointer array to channel buffers
	\param frames	number of maximum frames to get
	\return			frames put into buffers
*/
int Stream::doGet(int ch,float *const *buf,int frames,float sr)
{
	ASSERT(ch > 0 && frames >= 0 && sr > 0);

	if(isOk() && !isInitializing()) {
		// signal thread worker
		pthread_cond_signal(&cond);

		// check/(re)allocate buffers

		int strch = getChannels();
		if(bufs && bufch < strch) { 
			delete[] decoded;
			for(int i = 0; i < bufch; ++i) src_delete(src_state[i]);
			delete[] src_state;
			delete[] bufs;	bufs = NULL; 
		}

		if(!bufs) {
			if(bufch < strch) bufch = strch;
			bufs = new float *[bufch];
			decoded = new Fifo<float>[bufch];

			src_state = new SRC_STATE *[bufch];
			for(int i = 0; i < bufch; ++i) {
				int error;
				src_state[i] = src_new(SRC_ZERO_ORDER_HOLD,1,&error);
				if(!src_state[i]) post("src init error %i",error);
			}
		}

		// get frames

		float ratio = sr/getSamplerate();
		int frneed = (int)(frames/ratio)+DECMORE;  // number of frames to read from decoder fifo

		if(decoded[0].Size() < frneed) {
			// fifos are too small -> resize them (while keeping their contents)
			for(int i = 0; i < bufch; ++i) decoded[i].Resize(frneed,true);
		}

		// how many frames do we need to get from decoder?
		int frread = frneed-decoded[0].Have();

		int ret = state == ST_WAIT?0:DataRead(frread);

		if(ret < 0) {
			if(debug) post("read error");
			// clear output
			for(int c = 0; c < ch; ++c)
				memset(buf[c],0,frames*sizeof *buf[c]);
			return 0;
		}
		else {
			// how many channels do we really need for output?
			// this should be set elsewhere, because we can't change anyway!!! 
			// (SRC_STATE for dangling channels would be incorrect)
			int cmin = strch;
			if(ch < cmin) cmin = ch;

			// write data to fifo
			for(int i = 0; i < cmin; ++i) {
				int wr = decoded[i].Write(ret,bufs[i]);
				if(wr < ret) post("fifo overflow");
			}

//			state = ST_PROCESS;

			if(ratio == 1) {
				// no resampling necessary

				// hopefully all channel fifos advance uniformly.....
				for(int i = 0; i < cmin; ++i) {

					for(int got = 0; got < frames; ) {
						int cnt = frames-got;

						if(decoded[i].Have()) {
							got += decoded[i].Read(cnt,buf[i]+got);
						}
						else {
							state = ST_WAIT;
							if(debug) post("fifo underrun");

							// Buffer underrun!! -> zero output buffer
							memset(buf[i]+got,0,cnt*sizeof(*buf[i]));
							got += cnt;
						}
					}
				}
			}
			else 
			{
				SRC_DATA src_data;
				src_data.src_ratio = ratio;
				src_data.end_of_input = 0;

				// hopefully all channel fifos advance uniformly.....
				for(int i = 0; i < cmin; ++i) {
					src_set_ratio(src_state[i],ratio);

					for(int got = 0; got < frames; ) {
						src_data.data_out = buf[i]+got;
						src_data.output_frames = frames-got;

						if(decoded[i].Have()) {
							src_data.data_in = decoded[i].ReadPtr();
							src_data.input_frames = decoded[i].ReadSamples();

							int err = src_process(src_state[i],&src_data);
							if(err) post("src_process error %i",err);

							// advance buffer
							decoded[i].Read(src_data.input_frames_used,NULL);
						}
						else {
							state = ST_WAIT;
							if(debug) post("fifo underrun");

							// Buffer underrun!! -> zero output buffer
							memset(src_data.data_out,0,src_data.output_frames*sizeof(*src_data.data_out));
							src_data.output_frames_gen = src_data.output_frames;
						}
						got += src_data.output_frames_gen;
					}
				}
			}

			// zero remaining channels
			for(int c = cmin; c < ch; ++c)
				memset(buf[c],0,frames*sizeof *buf[c]);

			return ret;
		}
	}
	else {
		for(int c = 0; c < ch; ++c)
			memset(buf[c],0,frames*sizeof *buf[c]);
		return 0;
	}
}
Beispiel #13
0
void *jack_player_thread(void *unused){
	WfAudioInfo* nfo = &myplayer->info;
	const int nframes = 1024;
	float *tmpbuf = (float*) calloc(nframes * nfo->channels, sizeof(float));
	float *bufptr = tmpbuf;
#ifdef ENABLE_RESAMPLING
	size_t maxbufsiz = nframes;
	int err = 0;
	SRC_STATE* src_state = src_new(SRC_QUALITY, nfo->channels, NULL);
	SRC_DATA src_data;
	int nframes_r = floorf((float) nframes*m_fResampleRatio); ///< # of frames after resampling
#ifdef VARISPEED
	maxbufsiz = (2+nframes_r) * 2;
#else
	maxbufsiz = (1+nframes_r);
#endif
	float *smpbuf = (float*) calloc(maxbufsiz * nfo->channels, sizeof(float));

	src_data.input_frames  = nframes;
	src_data.output_frames = nframes_r;
	src_data.end_of_input  = 0;
	src_data.src_ratio     = m_fResampleRatio;
	src_data.input_frames_used = 0;
	src_data.output_frames_gen = 0;
	src_data.data_in       = tmpbuf;
	src_data.data_out      = smpbuf;
#else
	int nframes_r = nframes; // no resampling
#endif

	int ladspaerr = 0;
#if (defined ENABLE_LADSPA)
	if (m_use_effect && play->enable_effect) {
		int i;
		for(i=0;i<nfo->channels;i++) {
			ladspaerr |= ladspah_init(myplugin[i], m_use_effect, m_effectno, 
					jack_get_sample_rate(j_client) /* m_samplerate */, maxbufsiz);
		}
		if (ladspaerr) {
			dbg(0, "error setting up LADSPA plugin - effect disabled.\n");
		}
	} else {
		ladspaerr = 1;
	}
	play->effect_enabled = ladspaerr ? false : true; // read-only for GUI
#endif

	size_t rbchunk = nframes_r * nfo->channels * sizeof(float);
	play_position = 0;
	int64_t decoder_position = 0;

	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
	pthread_mutex_lock(&player_thread_lock);

	/** ALL SYSTEMS GO **/
	player_active = 1;
	while(thread_run) {
		int rv = ad_read(myplayer, tmpbuf, nframes * nfo->channels);

		if (rv > 0) decoder_position += rv / nfo->channels;

#ifdef JACK_MIDI
		const float pp[3] = {play->effect_param[0], play->effect_param[1] + midi_note, play->effect_param[2] + midi_octave};
#else
		const float pp[3] = {play->effect_param[0], play->effect_param[1], play->effect_param[2]};
#endif
#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
		const float varispeed = play->playback_speed;
#if 0
		/* note: libsamplerate slowly approaches a new sample-rate slowly
		 * src_set_ratio() allow for immediate updates at loss of quality */
		static float oldspd = -1;
		if (oldspd != varispeed) {
			if ((err = src_set_ratio(src_state, m_fResampleRatio * varispeed))) dbg(0, "SRC ERROR: %s", src_strerror(err)); // instant change.
			oldspd = varispeed;
		}
#endif
		nframes_r = floorf((float) nframes * m_fResampleRatio * varispeed); ///< # of frames after resampling
		src_data.input_frames  = nframes;
		src_data.output_frames = nframes_r;
		src_data.src_ratio     = m_fResampleRatio * varispeed;
		src_data.end_of_input  = 0;
#endif

		if (rv != nframes * nfo->channels) {
			dbg(1, "end of file.");
			if (rv > 0) {
#ifdef ENABLE_RESAMPLING
# ifdef VARISPEED
				if (1) 
# else
				if(m_fResampleRatio != 1.0)
# endif
				{
					src_data.input_frames = rv / nfo->channels;
#ifdef VARISPEED
					src_data.output_frames = floorf((float)(rv / nfo->channels) * m_fResampleRatio * varispeed);
#else
					src_data.output_frames = floorf((float)(rv / nfo->channels) * m_fResampleRatio);
#endif
					src_data.end_of_input = play->config.loop ? 0 : 1;
					src_process(src_state, &src_data);
					bufptr = smpbuf;
					rv = src_data.output_frames_gen * nfo->channels;
				}
#endif
				if (!ladspaerr) {
					ladspah_set_param(myplugin, nfo->channels, 0 /*cents */, pp[0]); /* -100 .. 100 */
					ladspah_set_param(myplugin, nfo->channels, 1 /*semitones */, pp[1]); /* -12 .. 12 */
					ladspah_set_param(myplugin, nfo->channels, 2 /*octave */, pp[2]);    /*  -3 ..  3 */
					ladspah_process_nch(myplugin, nfo->channels, bufptr, rv / nfo->channels);
				}
				jack_ringbuffer_write(rb, (char *) bufptr, rv *  sizeof(float));
			}
			if (play->config.loop) {
				ad_seek(myplayer, 0);
				decoder_position = 0;
#ifdef ENABLE_RESAMPLING
				//src_reset (src_state); // XXX causes click
# ifdef VARISPEED
				if (1) 
# else
				if(m_fResampleRatio != 1.0)
# endif
				{
					src_data.end_of_input  = 0;
					src_data.input_frames  = nframes;
					src_data.output_frames = nframes_r;
				}
#endif
#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
				while(thread_run && jack_ringbuffer_write_space(rb) <= maxbufsiz*nfo->channels*sizeof(float))
#else
				while(thread_run && jack_ringbuffer_write_space(rb) <= rbchunk)
#endif
				{
					pthread_cond_wait(&buffer_ready, &player_thread_lock);
				}
				continue;
			}
			else
				break;
		} /* end EOF handling */

#ifdef ENABLE_RESAMPLING
#ifdef VARISPEED
		if(1) // m_fResampleRatio*varispeed != 1.0)
#else
		if(m_fResampleRatio != 1.0)
#endif
		{
			if ((err=src_process(src_state, &src_data))) {
				dbg(0, "SRC PROCESS ERROR: %s", src_strerror(err));
			}
			bufptr = smpbuf;
			rbchunk = src_data.output_frames_gen * nfo->channels * sizeof(float);
		}
#endif
		if (!ladspaerr) {
			ladspah_set_param(myplugin, nfo->channels, 0 /*cent */, pp[0]); /* -100 .. 100 */
			ladspah_set_param(myplugin, nfo->channels, 1 /*semitones */, pp[1]); /* -12 .. 12 */
			ladspah_set_param(myplugin, nfo->channels, 2 /*octave */, pp[2]);    /*  -3 ..  3 */
			ladspah_process_nch(myplugin, nfo->channels, bufptr, rbchunk/ nfo->channels / sizeof(float));
		}
		jack_ringbuffer_write(rb, (char *) bufptr, rbchunk);

#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
		while(thread_run && jack_ringbuffer_write_space(rb) <= maxbufsiz*nfo->channels*sizeof(float))
#else
		while(thread_run && jack_ringbuffer_write_space(rb) <= rbchunk) 
#endif
		{
#if 1 // flush_ringbuffer on seek
			if (playpause && seek_request != -1) break; 
#endif
			pthread_cond_wait(&buffer_ready, &player_thread_lock);
		}

		/* Handle SEEKs */
		while (seek_request>=0 && seek_request<=1) {
			double csr = seek_request;
			decoder_position = floor(m_frames * seek_request);
			ad_seek(myplayer, decoder_position);
			if (csr == seek_request) {
				seek_request = -1;
#if 1 // flush_ringbuffer !
				size_t rs=jack_ringbuffer_read_space(rb);
				jack_ringbuffer_read_advance(rb,rs);
#endif
				break;
			}
		}
#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
		update_playposition (decoder_position, varispeed);
#else
		update_playposition (decoder_position, 1.0);
#endif
	}

	/** END OF PLAYBACK **/
#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
	const float varispeed = play->playback_speed;
#else
	const float varispeed = 1.0;
#endif
	pthread_mutex_unlock(&player_thread_lock);

	if (thread_run) {
		// wait for ringbuffer to empty.
		while (!silent && !playpause) {
			usleep(20);
			update_playposition (decoder_position, varispeed);
		}
		thread_run = 0;
		player_active = 0;
		play->effect_enabled = false;
		int i;
		for(i=0;i<nfo->channels;i++) {
			ladspah_deinit(myplugin[i]);
		}
		JACKclose(); 
	}
	free(tmpbuf);
#ifdef ENABLE_RESAMPLING
	src_delete(src_state);
	free(smpbuf);
#endif
	player_active = 0;
	if(play->status != PLAY_PLAY_PENDING){
		play->next();
	}
	return NULL;
}
Beispiel #14
0
static void
callback_reset_test (int converter)
{   static TEST_CB_DATA test_callback_data ;

    static float output [BUFFER_LEN] ;

    SRC_STATE *src_state ;

    double src_ratio = 1.1 ;
    long read_count, read_total ;
    int k, error ;

    printf ("\tcallback_reset_test (%-28s) ....... ", src_get_name (converter)) ;
    fflush (stdout) ;

    for (k = 0 ; k < ARRAY_LEN (data_one) ; k++)
    {   data_one [k] = 1.0 ;
        data_zero [k] = 0.0 ;
    } ;

    if ((src_state = src_callback_new (test_callback_func, converter, 1, &error, &test_callback_data)) == NULL)
    {   printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Process a bunch of 1.0 valued samples. */
    test_callback_data.channels = 1 ;
    test_callback_data.count = 0 ;
    test_callback_data.total = ARRAY_LEN (data_one) ;
    test_callback_data.data = data_one ;

    read_total = 0 ;
    do
    {   read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ;
        read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ;
        read_total += read_count ;
    }
    while (read_count > 0) ;

    /* Check for errors. */
    if ((error = src_error (src_state)) != 0)
    {   printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Reset the state of the converter.*/
    src_reset (src_state) ;

    /* Process a bunch of 0.0 valued samples. */
    test_callback_data.channels = 1 ;
    test_callback_data.count = 0 ;
    test_callback_data.total = ARRAY_LEN (data_zero) ;
    test_callback_data.data = data_zero ;

    /* Now process some zero data. */
    read_total = 0 ;
    do
    {   read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ;
        read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ;
        read_total += read_count ;
    }
    while (read_count > 0) ;

    /* Check for errors. */
    if ((error = src_error (src_state)) != 0)
    {   printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Finally make sure that the output data is zero ie reset was sucessful. */
    for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
        if (output [k] != 0.0)
        {   printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n\n", __LINE__, k, output [k]) ;
            save_oct_float ("output.dat", data_one, ARRAY_LEN (data_one), output, ARRAY_LEN (output)) ;
            exit (1) ;
        } ;

    /* Make sure that this function has been exported. */
    src_set_ratio (src_state, 1.0) ;

    /* Delete converter. */
    src_state = src_delete (src_state) ;

    puts ("ok") ;
} /* callback_reset_test */
Beispiel #15
0
void *AlsaCallback(void *ptr)
{
#ifdef ALSA
  static DevAlsa *dev=NULL;
  static float pcm_s1[32768];
  static float *pcm_s2;
  static float *pcm_s3;
  static int16_t pcm16[32768];
  static int32_t pcm32[32768];
  static int n;
  static SRC_STATE *src=NULL;
  static SRC_DATA data;
  static int err;
  static unsigned ring_frames=0;
  static unsigned count=0;
  static bool show_xrun=false;
  static double pll_setpoint_ratio;
  static float lvls[MAX_AUDIO_CHANNELS];
  static unsigned i;

  dev=(DevAlsa *)ptr;
  src=NULL;
  pll_setpoint_ratio=1.0;
  dev->alsa_pll_setpoint_frames=0;
  dev->alsa_pll_offset=0.0;
  ring_frames=0;
  count=0;
  show_xrun=false;
  dev->alsa_play_position=0;

  //
  // Initialize sample rate converter
  //
  pcm_s2=new float[262144];
  memset(&data,0,sizeof(data));
  data.data_in=pcm_s1;
  data.data_out=pcm_s2;
  data.output_frames=262144/dev->alsa_channels;
  pll_setpoint_ratio=
    (double)dev->alsa_samplerate/(double)dev->codec()->samplerate();
  data.src_ratio=pll_setpoint_ratio;
  if((src=src_new(SRC_LINEAR,dev->codec()->channels(),&err))==NULL) {
    fprintf(stderr,"SRC initialization error [%s]\n",src_strerror(err));
    exit(GLASS_EXIT_SRC_ERROR);
  }

  //
  // Initialize channel mixdown buffer
  //
  if(dev->codec()->channels()==dev->alsa_channels) {
    pcm_s3=pcm_s2;
  }
  else {
    pcm_s3=new float[32768];
  }

  //
  // Wait for PCM buffer to fill
  //
  while((!dev->alsa_stopping)&&
	(dev->codec()->ring()->readSpace()<2*dev->codec()->samplerate())) {
    usleep(36);
  }

  while(count<PLL_SETTLE_INTERVAL) {  // Allow ringbuffer to stabilize
    if((ring_frames=dev->codec()->ring()->readSpace())>dev->alsa_pll_setpoint_frames) {
      dev->alsa_pll_setpoint_frames=ring_frames;
    }
    dev->alsa_pll_setpoint_frames=ring_frames;
    count++;
  }
  while(!dev->alsa_stopping) {
    ring_frames=dev->codec()->ring()->readSpace();
    if(ring_frames>dev->alsa_pll_setpoint_frames) {
      if(dev->alsa_pll_offset>(-PLL_CORRECTION_LIMIT)) {
	dev->alsa_pll_offset-=PLL_CORRECTION;
      }
    }
    else {
      if(dev->alsa_pll_offset<(PLL_CORRECTION_LIMIT)) {
	dev->alsa_pll_offset+=PLL_CORRECTION;
      }
    }
    data.src_ratio=pll_setpoint_ratio+dev->alsa_pll_offset;
    src_set_ratio(src,data.src_ratio);
    if(snd_pcm_state(dev->alsa_pcm)!=SND_PCM_STATE_RUNNING) {
      if(show_xrun) {
	fprintf(stderr,"*** XRUN ***\n");
	snd_pcm_drop(dev->alsa_pcm);
	snd_pcm_prepare(dev->alsa_pcm);
	show_xrun=false;
      }
    }
    else {
      show_xrun=!dev->codec()->ring()->isFinished();
    }
    if((n=dev->codec()->ring()->
	read(pcm_s1,dev->alsa_buffer_size/(dev->alsa_period_quantity*2)))>0) {
      if(src!=NULL) {
	data.input_frames=n;
	dev->alsa_play_position+=n;
	if((err=src_process(src,&data))<0) {
	  fprintf(stderr,"SRC processing error [%s]\n",src_strerror(err));
	  exit(GLASS_EXIT_SRC_ERROR);
	}
	n=data.output_frames_gen;
      }
      if(dev->codec()->channels()!=dev->alsa_channels) {
	dev->remixChannels(pcm_s3,dev->alsa_channels,
			   pcm_s2,dev->codec()->channels(),n);
      }
      switch(dev->alsa_format) {
      case AudioDevice::S16_LE:
	dev->convertFromFloat(pcm16,pcm_s3,n,dev->alsa_channels);
	snd_pcm_writei(dev->alsa_pcm,pcm16,n);
	break;

      case AudioDevice::S32_LE:
	dev->convertFromFloat(pcm32,pcm_s3,n,dev->alsa_channels);
	snd_pcm_writei(dev->alsa_pcm,pcm32,n);
	break;

      case AudioDevice::FLOAT:
	snd_pcm_writei(dev->alsa_pcm,pcm_s3,n);
	break;

      case AudioDevice::LastFormat:
	break;
      }
      dev->peakLevels(lvls,pcm_s3,n,dev->codec()->channels());
      for(i=0;i<dev->codec()->channels();i++) {
	dev->alsa_meter_avg[i]->addValue(lvls[i]);
      }
      dev->setMeterLevels(lvls);
    }
  }

  //
  // Shutdown
  //
  snd_pcm_drain(dev->alsa_pcm);
  snd_pcm_close(dev->alsa_pcm);
  if((pcm_s3!=pcm_s2)&&(pcm_s3!=pcm_s1)) {
    delete pcm_s3;
  }
  pcm_s3=NULL;
  if(pcm_s2!=pcm_s1) {
    delete pcm_s2;
  }
  pcm_s2=NULL;
#endif  // ALSA
  return NULL;
}
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 type, 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);

    /* Select conversion type */
    if (high_quality) {
	type = large_filter ? SRC_SINC_BEST_QUALITY : SRC_SINC_MEDIUM_QUALITY;
    } else {
	type = large_filter ? SRC_SINC_FASTEST : SRC_LINEAR;
    }

    /* Create converter */
    resample->state = src_new(type, channel_count, &err);
    if (resample->state == NULL) {
	PJ_LOG(4,(THIS_FILE, "Error creating resample: %s", 
		  src_strerror(err)));
	return PJMEDIA_ERROR;
    }

    /* Calculate ratio */
    resample->ratio = rate_out * 1.0 / rate_in;

    /* Calculate number of samples for input and output */
    resample->in_samples = samples_per_frame;
    resample->out_samples = rate_out / (rate_in / samples_per_frame);

    resample->frame_in = (float*) 
			 pj_pool_calloc(pool, 
					resample->in_samples + 8, 
					sizeof(float));

    resample->frame_out = (float*) 
			  pj_pool_calloc(pool, 
					 resample->out_samples + 8, 
					 sizeof(float));

    /* Set the converter ratio */
    err = src_set_ratio(resample->state, resample->ratio);
    if (err != 0) {
	PJ_LOG(4,(THIS_FILE, "Error creating resample: %s", 
		  src_strerror(err)));
	return PJMEDIA_ERROR;
    }

    /* Done */

    PJ_LOG(5,(THIS_FILE, 
	      "Resample using libsamplerate %s, type=%s (%s), "
	      "ch=%d, in/out rate=%d/%d", 
	      src_get_version(),
	      src_get_name(type), src_get_description(type),
	      channel_count, rate_in, rate_out));

    *p_resample = resample;

    return PJ_SUCCESS;
}
Beispiel #17
0
static void
process_reset_test (int converter)
{   static float output [BUFFER_LEN] ;

    SRC_STATE *src_state ;
    SRC_DATA src_data ;
    int k, error ;

    printf ("\tprocess_reset_test  (%-28s) ....... ", src_get_name (converter)) ;
    fflush (stdout) ;

    for (k = 0 ; k < BUFFER_LEN ; k++)
    {   data_one [k] = 1.0 ;
        data_zero [k] = 0.0 ;
    } ;

    /* Get a converter. */
    if ((src_state = src_new (converter, 1, &error)) == NULL)
    {   printf ("\n\nLine %d : src_new() failed : %s.\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Process a bunch of 1.0 valued samples. */
    src_data.data_in		= data_one ;
    src_data.data_out		= output ;
    src_data.input_frames	= BUFFER_LEN ;
    src_data.output_frames	= BUFFER_LEN ;
    src_data.src_ratio		= 0.9 ;
    src_data.end_of_input	= 1 ;

    if ((error = src_process (src_state, &src_data)) != 0)
    {   printf ("\n\nLine %d : src_simple () returned error : %s\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Reset the state of the converter.*/
    src_reset (src_state) ;

    /* Now process some zero data. */
    src_data.data_in		= data_zero ;
    src_data.data_out		= output ;
    src_data.input_frames	= BUFFER_LEN ;
    src_data.output_frames	= BUFFER_LEN ;
    src_data.src_ratio		= 0.9 ;
    src_data.end_of_input	= 1 ;

    if ((error = src_process (src_state, &src_data)) != 0)
    {   printf ("\n\nLine %d : src_simple () returned error : %s\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Finally make sure that the output data is zero ie reset was sucessful. */
    for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
        if (output [k] != 0.0)
        {   printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n", __LINE__, k, output [k]) ;
            exit (1) ;
        } ;

    /* Make sure that this function has been exported. */
    src_set_ratio (src_state, 1.0) ;

    /* Delete converter. */
    src_state = src_delete (src_state) ;

    puts ("ok") ;
} /* process_reset_test */