Exemplo n.º 1
0
AUDIODATA_EXPORT
float* readaudio(const char *filename, const int sr, float *sigbuf, unsigned int *buflen,\
                 const float nbsecs, AudioMetaData *mdata, int *error)
{
  long orig_sr;
  unsigned int orig_length = 0;
  float *inbuffer = NULL;
  *error = PHERR_SUCCESS;

  if (filename == NULL || buflen == NULL) {
    *error = PHERR_NULLARG;
    return NULL;
  }
  if (mdata) init_mdata(mdata);

  const char *suffix = strrchr(filename, '.');

  if (*suffix != '\0' && !strncasecmp(suffix+1, "mp3",3)) {
#ifdef HAVE_MPG123
    inbuffer = readaudio_mp3(filename, &orig_sr, &orig_length, nbsecs, mdata, error);
#endif /* HAVE_MPG123 */
  } else {
    inbuffer = readaudio_snd(filename, &orig_sr, &orig_length, nbsecs, mdata, error);
  }  

  if (inbuffer == NULL){
    return NULL;
  }

  /* if no data extracted for title, use the file name */ 
  if (mdata && mdata->title2 == NULL){
      char *name = strrchr(filename, '/');
      if (name == NULL) name = strchr(filename, '\\');
      if (name) mdata->title2 = strdup(name+1);
  }

  /* resample float array */ 
  /* set desired sr ratio */ 
  double sr_ratio = (double)(sr)/(double)orig_sr;
  if (src_is_valid_ratio(sr_ratio) == 0){
    *error = PHERR_BADSR;
    free(inbuffer);
    return NULL;
  }

  /* allocate output buffer for conversion */ 
  unsigned int outbufferlength = sr_ratio*(orig_length);

  float *outbuffer = NULL;
  if (sigbuf && outbufferlength < *buflen){
    outbuffer = sigbuf;
  } else {
    outbuffer = (float*)malloc(outbufferlength*sizeof(float));
  }

  if (!outbuffer){
    free(inbuffer);
    *error = PHERR_NOBUFALLOCD;
    return NULL;
  }

  SRC_STATE *src_state = src_new(SRC_LINEAR, 1, error);
  if (!src_state){
    *error = PHERR_SRCCONTXT;
    free(inbuffer);
    if (outbuffer != sigbuf) free(outbuffer);
     return NULL;
  }

  SRC_DATA src_data;
  src_data.data_in = inbuffer;
  src_data.data_out = outbuffer;
  src_data.input_frames = orig_length;
  src_data.output_frames = outbufferlength;
  src_data.end_of_input = SF_TRUE;
  src_data.src_ratio = sr_ratio;

  /* sample rate conversion */ 
  *error = src_process(src_state, &src_data);
  if (*error){
    *error = PHERR_SRCPROC;
    free(inbuffer);
    if (outbuffer != sigbuf) free(outbuffer);
    src_delete(src_state);
    return NULL;
  }

  *buflen = outbufferlength;

  src_delete(src_state);
  free(inbuffer);

  return outbuffer;
} 
Exemplo n.º 2
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 */
Exemplo n.º 3
0
static void
process_test (int converter, int channel_count, double target_snr)
{	SRC_STATE	*src_state ;
	SRC_DATA	src_data ;

	double	freq, snr ;
	int		ch, error, frames, current_in, current_out ;

	printf ("\t%-22s (%d channel%c) ............. ", "process_test", channel_count, channel_count > 1 ? 's' : ' ') ;
	fflush (stdout) ;

	memset (input_serial, 0, sizeof (input_serial)) ;
	memset (input_interleaved, 0, sizeof (input_interleaved)) ;
	memset (output_interleaved, 0, sizeof (output_interleaved)) ;
	memset (output_serial, 0, sizeof (output_serial)) ;

	frames = MIN (ARRAY_LEN (input_serial) / channel_count, 1 << 16) ;

	/* Calculate channel_count separate windowed sine waves. */
	for (ch = 0 ; ch < channel_count ; ch++)
	{	freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
		gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
		} ;

	/* Interleave the data in preparation for SRC. */
	interleave_data (input_serial, input_interleaved, frames, channel_count) ;

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

	src_data.end_of_input = 0 ; /* Set this later. */

	/* Choose a converstion ratio < 1.0. */
	src_data.src_ratio = 0.95 ;

	src_data.data_in = input_interleaved ;
	src_data.data_out = output_interleaved ;

	current_in = current_out = 0 ;

	while (1)
	{	src_data.input_frames	= MAX (MIN (BLOCK_LEN, frames - current_in), 0) ;
		src_data.output_frames	= MAX (MIN (BLOCK_LEN, frames - current_out), 0) ;

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

		if (src_data.end_of_input && src_data.output_frames_gen == 0)
			break ;

		current_in	+= src_data.input_frames_used ;
		current_out += src_data.output_frames_gen ;

		src_data.data_in	+= src_data.input_frames_used * channel_count ;
		src_data.data_out	+= src_data.output_frames_gen * channel_count ;

		src_data.end_of_input = (current_in >= frames) ? 1 : 0 ;
		} ;

	src_state = src_delete (src_state) ;

	if (fabs (current_out - src_data.src_ratio * current_in) > 2)
	{	printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
					current_out, (int) floor (src_data.src_ratio * current_in)) ;
		printf ("\tsrc_ratio  : %.4f\n", src_data.src_ratio) ;
		printf ("\tinput_len  : %d\n", frames) ;
		printf ("\toutput_len : %d\n\n", current_out) ;
		exit (1) ;
		} ;

	/* De-interleave data so SNR can be calculated for each channel. */
	deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;

	for (ch = 0 ; ch < channel_count ; ch++)
	{	snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
		if (snr < target_snr)
		{	printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
			save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
			exit (1) ;
			} ;
		} ;

	puts ("ok") ;

	return ;
} /* process_test */
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
Arquivo: jack.c Projeto: BG2BKK/cmus
static int op_jack_init(void)
{
#ifdef HAVE_SAMPLERATE
	for (int i = 0; i < CHANNELS; i++) {
		src_state[i] = src_new(src_quality, 1, NULL);
		if (src_state[i] == NULL) {
			d_print("src_new failed");
			for (i = i - 1; i >= 0; i--) {
				src_delete(src_state[i]);
			}
			return -OP_ERROR_INTERNAL;
		}
	}
#endif
	jack_set_error_function(op_jack_error_cb);

	jack_options_t options = JackNullOption;
	if (fail) {
		/* since jackd failed, it will not be autostarted. Either jackd
		 * was killed intentionaly or it died by heartattack.
		 * Until it is restarted, init will happily fail again
		 * and again and again..
		 */
		options |= JackNoStartServer;
	}

	jack_status_t status;
	client = jack_client_open("cmus", options, &status, server_name);
	if (client == NULL) {
		d_print("jack_client_new failed\n");
		return -OP_ERROR_INTERNAL;
	}

	if (status & JackServerStarted) {
		d_print("jackd started\n");
	}

	jack_nframes_t jack_buffer_size = jack_get_buffer_size(client);
	jack_sample_rate = jack_get_sample_rate(client);
	op_jack_buffer_init(jack_buffer_size, NULL);

	jack_set_process_callback(client, op_jack_cb, NULL);
	jack_set_sample_rate_callback(client, op_jack_sample_rate_cb, NULL);
	jack_set_buffer_size_callback(client, op_jack_buffer_init, NULL);
	jack_on_shutdown(client, op_jack_shutdown_cb, NULL);

	for (int i = 0; i < CHANNELS; i++) {
		char port_name[20];
		snprintf(port_name, sizeof(port_name)-1, "output %d", i);

		output_ports[i] = jack_port_register(
			client,
			port_name,
			JACK_DEFAULT_AUDIO_TYPE,
			JackPortIsOutput,
			0
		);
		if (output_ports[i] == NULL) {
			d_print("no jack ports available\n");
			return -OP_ERROR_INTERNAL;
		}
	}

	if (jack_activate(client)) {
		d_print("jack_client_activate failed\n");
		return -OP_ERROR_INTERNAL;
	}

	const char **ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
	if (ports == NULL) {
		d_print("cannot get playback ports\n");
		return -OP_ERROR_INTERNAL;
	}

	for (int i = 0; i < CHANNELS; i++) {
		if (ports[i] == NULL) {
			d_print("could not connect output %d. too few ports.\n", i);
			break;
		}
		if (jack_connect(client, jack_port_name(output_ports[i]), ports[i])) {
			d_print("connot connect port %s\n", ports[i]);
			jack_free(ports);
			return -OP_ERROR_INTERNAL;
		}
	}

	jack_free(ports);
	fail = 0;

	return OP_ERROR_SUCCESS;
}
Exemplo n.º 6
0
void sf2Instrument::updateSampleRate()
{
	double tempRate;

	// Set & get, returns the true sample rate
	fluid_settings_setnum( m_settings, (char *) "synth.sample-rate", Engine::mixer()->processingSampleRate() );
	fluid_settings_getnum( m_settings, (char *) "synth.sample-rate", &tempRate );
	m_internalSampleRate = static_cast<int>( tempRate );

	if( m_font )
	{
		// Now, delete the old one and replace
		m_synthMutex.lock();
		fluid_synth_remove_sfont( m_synth, m_font->fluidFont );
		delete_fluid_synth( m_synth );

		// New synth
		m_synth = new_fluid_synth( m_settings );
		m_fontId = fluid_synth_add_sfont( m_synth, m_font->fluidFont );
		m_synthMutex.unlock();

		// synth program change (set bank and patch)
		updatePatch();
	}
	else
	{
		// Recreate synth with no soundfonts
		m_synthMutex.lock();
		delete_fluid_synth( m_synth );
		m_synth = new_fluid_synth( m_settings );
		m_synthMutex.unlock();
	}

	m_synthMutex.lock();
	if( Engine::mixer()->currentQualitySettings().interpolation >=
			Mixer::qualitySettings::Interpolation_SincFastest )
	{
		fluid_synth_set_interp_method( m_synth, -1, FLUID_INTERP_7THORDER );
	}
	else
	{
		fluid_synth_set_interp_method( m_synth, -1, FLUID_INTERP_DEFAULT );
	}
	m_synthMutex.unlock();
	if( m_internalSampleRate < Engine::mixer()->processingSampleRate() )
	{
		m_synthMutex.lock();
		if( m_srcState != NULL )
		{
			src_delete( m_srcState );
		}
		int error;
		m_srcState = src_new( Engine::mixer()->currentQualitySettings().libsrcInterpolation(), DEFAULT_CHANNELS, &error );
		if( m_srcState == NULL || error )
		{
			qCritical( "error while creating libsamplerate data structure in Sf2Instrument::updateSampleRate()" );
		}
		m_synthMutex.unlock();
	}
	updateReverb();
	updateChorus();
	updateReverbOn();
	updateChorusOn();
	updateGain();

	// Reset last MIDI pitch properties, which will be set to the correct values
	// upon playing the next note
	m_lastMidiPitch = -1;
	m_lastMidiPitchRange = -1;
}
Exemplo n.º 7
0
static void
stream_test (int converter, double src_ratio)
{	static float input [LONG_BUFFER_LEN], output [LONG_BUFFER_LEN] ;

	SRC_STATE	*src_state ;
	SRC_DATA	src_data ;

	int input_len, output_len, current_in, current_out ;
	int k, error, terminate ;

	printf ("\tstream_test      (SRC ratio = %7.4f) .......... ", src_ratio) ;
	fflush (stdout) ;

/* Erik */
for (k = 0 ; k < LONG_BUFFER_LEN ; k++) input [k] = k * 1.0 ;

	/* Calculate maximun input and output lengths. */
	if (src_ratio >= 1.0)
	{	output_len = LONG_BUFFER_LEN ;
		input_len = (int) floor (LONG_BUFFER_LEN / src_ratio) ;
		}
	else
	{	input_len = LONG_BUFFER_LEN ;
		output_len = (int) floor (LONG_BUFFER_LEN * src_ratio) ;
		} ;

	/* Reduce input_len by 10 so output is longer than necessary. */
	input_len -= 20 ;

	if (output_len > LONG_BUFFER_LEN)
	{	printf ("\n\nLine %d : output_len > LONG_BUFFER_LEN\n\n", __LINE__) ;
		exit (1) ;
		} ;

	current_in = current_out = 0 ;

	/* Perform sample rate conversion. */
	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) ;
		} ;

	src_data.end_of_input = 0 ; /* Set this later. */

	src_data.data_in = input ;

	src_data.src_ratio = src_ratio ;

	src_data.data_out = output ;
	src_data.output_frames = ARRAY_LEN (output) / 10 ;

	terminate = 1 + (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;

	while (1)
	{
		src_data.input_frames = next_block_length (0) ;
		src_data.input_frames = MIN (src_data.input_frames, input_len - current_in) ;

		src_data.output_frames = ARRAY_LEN (output) - current_out ;
		/*-Erik MIN (src_data.output_frames, output_len - current_out) ;-*/

		src_data.end_of_input = (current_in >= input_len) ? 1 : 0 ;

		if ((error = src_process (src_state, &src_data)))
		{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
			printf ("  src_data.input_frames  : %ld\n", src_data.input_frames) ;
			printf ("  src_data.output_frames : %ld\n\n", src_data.output_frames) ;
			exit (1) ;
			} ;

		if (src_data.end_of_input && src_data.output_frames_gen == 0)
			break ;

		if (src_data.input_frames_used > src_data.input_frames)
		{	printf ("\n\nLine %d : input_frames_used > input_frames\n\n", __LINE__) ;
			printf ("  src_data.input_frames      : %ld\n", src_data.input_frames) ;
			printf ("  src_data.input_frames_used : %ld\n", src_data.input_frames_used) ;
			printf ("  src_data.output_frames     : %ld\n", src_data.output_frames) ;
			printf ("  src_data.output_frames_gen : %ld\n\n", src_data.output_frames_gen) ;
			exit (1) ;
			} ;

		if (src_data.input_frames_used < 0)
		{	printf ("\n\nLine %d : input_frames_used (%ld) < 0\n\n", __LINE__, src_data.input_frames_used) ;
			exit (1) ;
			} ;

		if (src_data.output_frames_gen < 0)
		{	printf ("\n\nLine %d : output_frames_gen (%ld) < 0\n\n", __LINE__, src_data.output_frames_gen) ;
			exit (1) ;
			} ;

		current_in	+= src_data.input_frames_used ;
		current_out += src_data.output_frames_gen ;

		if (current_in > input_len + terminate)
		{	printf ("\n\nLine %d : current_in (%d) > input_len (%d + %d)\n\n", __LINE__, current_in, input_len, terminate) ;
			exit (1) ;
			} ;

		if (current_out > output_len)
		{	printf ("\n\nLine %d : current_out (%d) > output_len (%d)\n\n", __LINE__, current_out, output_len) ;
			exit (1) ;
			} ;

		if (src_data.input_frames_used > input_len)
		{	printf ("\n\nLine %d : input_frames_used (%ld) > %d\n\n", __LINE__, src_data.input_frames_used, input_len) ;
			exit (1) ;
			} ;

		if (src_data.output_frames_gen > output_len)
		{	printf ("\n\nLine %d : output_frames_gen (%ld) > %d\n\n", __LINE__, src_data.output_frames_gen, output_len) ;
			exit (1) ;
			} ;

		if (src_data.data_in == NULL && src_data.output_frames_gen == 0)
			break ;


		src_data.data_in	+= src_data.input_frames_used ;
		src_data.data_out	+= src_data.output_frames_gen ;
		} ;

	src_state = src_delete (src_state) ;

	if (fabs (current_out - src_ratio * input_len) > terminate)
	{	printf ("\n\nLine %d : bad output data length %d should be %2.1f +/- %d.\n", __LINE__,
					current_out, src_ratio * input_len, terminate) ;
		printf ("\tsrc_ratio  : %.4f\n", src_ratio) ;
		printf ("\tinput_len  : %d\n\tinput_used : %d\n", input_len, current_in) ;
		printf ("\toutput_len : %d\n\toutput_gen : %d\n\n", output_len, current_out) ;
		exit (1) ;
		} ;

	if (current_in != input_len)
	{	printf ("\n\nLine %d : unused input.\n", __LINE__) ;
		printf ("\tinput_len         : %d\n", input_len) ;
		printf ("\tinput_frames_used : %d\n\n", current_in) ;
		exit (1) ;
		} ;

	puts ("ok") ;

	return ;
} /* stream_test */
Exemplo n.º 8
0
SampleBuffer::handleState::~handleState()
{
	src_delete( m_resamplingData );
}
Exemplo n.º 9
0
static
int encode_sndfile(SNDFILE* snd, SF_INFO* info, pcm_sample_description_t* format,
           HANDLE_AACENCODER encoder,
           uint32_t frame_length, FILE *ofp, m4af_ctx_t *m4af,
           int show_progress)
{
#ifdef USE_LIBSAMPLERATE
    //short *resamplebuf = 0;
    SRC_STATE* srcstate = NULL;
    SRC_DATA srcdata;
    int srcerror = 0;
    float *ibuf = 0;
#else
    short *ibuf = 0;
#endif

    int16_t *pcmbuf = 0;
    uint32_t pcmsize = 0;
    uint8_t *obuf = 0;
    uint32_t olen;
    uint32_t osize = 0;
    int nread = 1;
    int consumed, written;
    int rc = -1;
    int frames_written = 0;
    aacenc_progress_t progress = { 0 };

    ibuf = malloc(frame_length * format->bytes_per_frame);
#ifdef USE_LIBSAMPLERATE
    if(format->sample_rate != info->samplerate) {
        /* set up resampler */
        srcstate = src_new(SRC_SINC_MEDIUM_QUALITY, info->channels, &srcerror);
        srcdata.src_ratio = format->sample_rate; srcdata.src_ratio /= info->samplerate;
        srcdata.data_in = ibuf;
        srcdata.data_out = malloc(frame_length * format->bytes_per_frame * srcdata.src_ratio);
        srcdata.end_of_input = 0;
    }

#endif
    aacenc_progress_init(&progress, info->frames, info->samplerate);
    do {
        if (g_interrupted)
            nread = 0;
        else if (nread) {
#ifdef USE_LIBSAMPLERATE
            if ((nread = sf_readf_float(snd, ibuf, frame_length)) < 0) {
#else
            if ((nread = sf_readf_short(snd, ibuf, frame_length)) < 0) {
#endif
                fprintf(stderr, "ERROR: read failed\n");
                goto END;
            } else if (nread > 0) {
                float* in_buf = ibuf;
#ifdef USE_LIBSAMPLERATE
                if(srcstate) {
                    /* run converstion */
                    srcdata.input_frames = nread;
                    srcdata.output_frames = frame_length;
                    if(srcerror = src_process(srcstate, &srcdata)) {
                        fprintf(stderr, "resample error: %s\n", src_strerror(srcerror));
                        goto END;
                    }
                    //printf("resampled %d samples to %d samples\n", srcdata.input_frames_used, srcdata.output_frames_gen);
                    in_buf = srcdata.data_out;
                    nread = srcdata.output_frames_gen;
                }
#endif
                if (pcm_convert_to_native_sint16(format, in_buf, nread,
                                                 &pcmbuf, &pcmsize) < 0) {
                    fprintf(stderr, "ERROR: unsupported sample format\n");
                    goto END;
                }
            }
            if (show_progress)
                aacenc_progress_update(&progress, sf_seek(snd, 0, SEEK_CUR),
                                       info->samplerate * 2);
        }
        written = nread;
        do {
            if ((consumed = aac_encode_frame(encoder, format, pcmbuf + (nread-written)*info->channels, written,
                                             &obuf, &olen, &osize)) < 0)
                goto END;
            //printf("nread: %d consumed: %d olen: %d\n", nread, consumed, olen);
            written -= (consumed / info->channels);
            if (olen > 0) {
                if (write_sample(ofp, m4af, obuf, olen, frame_length) < 0)
                    goto END;
                ++frames_written;
                //printf("wrote frame %d\n", frames_written);
            }
        } while (written > 0);
    } while (nread > 0 || olen > 0);

    if (show_progress)
        aacenc_progress_finish(&progress, sf_seek(snd, 0, SEEK_CUR));
    rc = frames_written;
END:
    if (ibuf) free(ibuf);
    if (pcmbuf) free(pcmbuf);
    if (obuf) free(obuf);
#ifdef USE_SAMPLERATE
    if (srcstate) {
        free(srcdata.data_out);
        src_delete(srcstate);
    }
#endif
    return rc;
}
#endif


static
int encode(wav_reader_t *wavf, HANDLE_AACENCODER encoder,
           uint32_t frame_length, FILE *ofp, m4af_ctx_t *m4af,
           int show_progress)
{
    uint8_t *ibuf = 0;
    int16_t *pcmbuf = 0;
    uint32_t pcmsize = 0;
    uint8_t *obuf = 0;
    uint32_t olen;
    uint32_t osize = 0;
    int nread = 1;
    int consumed;
    int rc = -1;
    int frames_written = 0;
    aacenc_progress_t progress = { 0 };
    const pcm_sample_description_t *format = wav_get_format(wavf);

    ibuf = malloc(frame_length * format->bytes_per_frame);
    aacenc_progress_init(&progress, wav_get_length(wavf), format->sample_rate);
    do {
        if (g_interrupted)
            nread = 0;
        else if (nread) {
            if ((nread = wav_read_frames(wavf, ibuf, frame_length)) < 0) {
                fprintf(stderr, "ERROR: read failed\n");
                goto END;
            } else if (nread > 0) {
                if (pcm_convert_to_native_sint16(format, ibuf, nread,
                                                 &pcmbuf, &pcmsize) < 0) {
                    fprintf(stderr, "ERROR: unsupported sample format\n");
                    goto END;
                }
            }
            if (show_progress)
                aacenc_progress_update(&progress, wav_get_position(wavf),
                                       format->sample_rate * 2);
        }
        if ((consumed = aac_encode_frame(encoder, format, pcmbuf, nread,
                                         &obuf, &olen, &osize)) < 0)
            goto END;
        if (olen > 0) {
            if (write_sample(ofp, m4af, obuf, olen, frame_length) < 0)
                goto END;
            ++frames_written;
        }
    } while (nread > 0 || olen > 0);

    if (show_progress)
        aacenc_progress_finish(&progress, wav_get_position(wavf));
    rc = frames_written;
END:
    if (ibuf) free(ibuf);
    if (pcmbuf) free(pcmbuf);
    if (obuf) free(obuf);
    return rc;
}
Exemplo n.º 10
0
static sf_count_t
sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain, int normalize)
{	static float input [BUFFER_LEN] ;
	static float output [BUFFER_LEN] ;

	SRC_STATE	*src_state ;
	SRC_DATA	src_data ;
	int			error ;
	double		max = 0.0 ;
	sf_count_t	output_count = 0 ;

	sf_seek (infile, 0, SEEK_SET) ;
	sf_seek (outfile, 0, SEEK_SET) ;

	/* Initialize the sample rate converter. */
	if ((src_state = src_new (converter, channels, &error)) == NULL)
	{	printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ;
		exit (1) ;
		} ;

	src_data.end_of_input = 0 ; /* Set this later. */

	/* Start with zero to force load in while loop. */
	src_data.input_frames = 0 ;
	src_data.data_in = input ;

	src_data.src_ratio = src_ratio ;

	src_data.data_out = output ;
	src_data.output_frames = BUFFER_LEN /channels ;

	while (1)
	{
		/* If the input buffer is empty, refill it. */
		if (src_data.input_frames == 0)
		{	src_data.input_frames = sf_readf_float (infile, input, BUFFER_LEN / channels) ;
			src_data.data_in = input ;

			/* The last read will not be a full buffer, so snd_of_input. */
			if (src_data.input_frames < BUFFER_LEN / channels)
				src_data.end_of_input = SF_TRUE ;
			} ;

		if ((error = src_process (src_state, &src_data)))
		{	printf ("\nError : %s\n", src_strerror (error)) ;
			exit (1) ;
			} ;

		/* Terminate if done. */
		if (src_data.end_of_input && src_data.output_frames_gen == 0)
			break ;

		max = apply_gain (src_data.data_out, src_data.output_frames_gen, channels, max, *gain) ;

		/* Write output. */
		sf_writef_float (outfile, output, src_data.output_frames_gen) ;
		output_count += src_data.output_frames_gen ;

		src_data.data_in += src_data.input_frames_used * channels ;
		src_data.input_frames -= src_data.input_frames_used ;
		} ;

	src_delete (src_state) ;

	if (normalize && max > 1.0)
	{	*gain = 1.0 / max ;
		printf ("\nOutput has clipped. Restarting conversion to prevent clipping.\n\n") ;
		return -1 ;
		} ;

	return output_count ;
} /* sample_rate_convert */
Exemplo n.º 11
0
	bool Init()
	{
		int ret = 0;

		mPMainLoop = pa_threaded_mainloop_new();
		pa_mainloop_api *mlapi = pa_threaded_mainloop_get_api(mPMainLoop);

		mPContext = pa_context_new (mlapi, "USBqemu-pulse");

		ret = pa_context_connect (mPContext,
			mServer,
			PA_CONTEXT_NOFLAGS,
			NULL
		);

		OSDebugOut("pa_context_connect %s\n", pa_strerror(ret));
		if (ret != PA_OK)
			goto error;

		pa_context_set_state_callback(mPContext,
			pa_context_state_cb,
			&mPAready
		);

		pa_threaded_mainloop_start(mPMainLoop);

		// wait for pa_context_state_cb
		for(;;)
		{
			if(mPAready == 1) break;
			if(mPAready == 2 || mQuit) goto error;
		}

		mStream = pa_stream_new(mPContext,
			"USBqemu-pulse",
			&mSSpec,
			NULL
		);

		pa_stream_set_read_callback(mStream,
			stream_read_cb,
			this
		);

		// Sets individual read callback fragsize but recording itself
		// still "lags" ~1sec (read_cb is called in bursts) without
		// PA_STREAM_ADJUST_LATENCY
		pa_buffer_attr buffer_attr;
		buffer_attr.maxlength = (uint32_t) -1;
		buffer_attr.tlength = (uint32_t) -1;
		buffer_attr.prebuf = (uint32_t) -1;
		buffer_attr.minreq = (uint32_t) -1;
		buffer_attr.fragsize = pa_usec_to_bytes(mBuffering * 1000, &mSSpec);
		OSDebugOut("usec_to_bytes %zu\n", buffer_attr.fragsize);

		ret = pa_stream_connect_record(mStream,
			mDevice.c_str(),
			&buffer_attr,
			PA_STREAM_ADJUST_LATENCY
		);

		OSDebugOut("pa_stream_connect_record %s\n", pa_strerror(ret));
		if (ret != PA_OK)
			goto error;

		// Setup resampler
		if (mResampler)
			mResampler = src_delete(mResampler);

		mResampler = src_new(SRC_SINC_FASTEST, mSSpec.channels, &ret);
		if (!mResampler)
		{
			OSDebugOut("Failed to create resampler: error %08X\n", ret);
			goto error;
		}

		mLastGetBuffer = hrc::now();
		return true;
	error:
		Uninit();
		return false;
	}
Exemplo n.º 12
0
SampleChannel::~SampleChannel() {
	if (wave)
		delete wave;
	src_delete(rsmp_state);
	free(pChan);
}
Exemplo n.º 13
0
static void
callback_test (int converter, int channel_count, double target_snr)
{	TEST_CB_DATA test_callback_data ;
	SRC_STATE	*src_state = NULL ;

	double	freq, snr, src_ratio ;
	int		ch, error, frames, read_total, read_count ;

	printf ("\t%-22s (%d channel%c) ............. ", "callback_test", channel_count, channel_count > 1 ? 's' : ' ') ;
	fflush (stdout) ;

	memset (input_serial, 0, sizeof (input_serial)) ;
	memset (input_interleaved, 0, sizeof (input_interleaved)) ;
	memset (output_interleaved, 0, sizeof (output_interleaved)) ;
	memset (output_serial, 0, sizeof (output_serial)) ;
	memset (&test_callback_data, 0, sizeof (test_callback_data)) ;

	frames = MIN (ARRAY_LEN (input_serial) / channel_count, 1 << 16) ;

	/* Calculate channel_count separate windowed sine waves. */
	for (ch = 0 ; ch < channel_count ; ch++)
	{	freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
		gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
		} ;

	/* Interleave the data in preparation for SRC. */
	interleave_data (input_serial, input_interleaved, frames, channel_count) ;

	/* Perform sample rate conversion. */
	src_ratio = 0.95 ;
	test_callback_data.channels = channel_count ;
	test_callback_data.total_frames = frames ;
	test_callback_data.current_frame = 0 ;
	test_callback_data.data = input_interleaved ;

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

	read_total = 0 ;
	while (read_total < frames)
	{	read_count = src_callback_read (src_state, src_ratio, frames - read_total, output_interleaved + read_total * channel_count) ;

		if (read_count <= 0)
			break ;

		read_total += read_count ;
		} ;

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

	src_state = src_delete (src_state) ;

	if (fabs (read_total - src_ratio * frames) > 2)
	{	printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
					read_total, (int) floor (src_ratio * frames)) ;
		printf ("\tsrc_ratio  : %.4f\n", src_ratio) ;
		printf ("\tinput_len  : %d\n", frames) ;
		printf ("\toutput_len : %d\n\n", read_total) ;
		exit (1) ;
		} ;

	/* De-interleave data so SNR can be calculated for each channel. */
	deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;

	for (ch = 0 ; ch < channel_count ; ch++)
	{	snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
		if (snr < target_snr)
		{	printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
			save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
			exit (1) ;
			} ;
		} ;

	puts ("ok") ;

	return ;
} /* callback_test */
Exemplo n.º 14
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 */
Exemplo n.º 15
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;
	}
}
Exemplo n.º 16
0
Resample::~Resample()
{
	src_delete(statel);
	src_delete(stater);
};
Exemplo n.º 17
0
static double
snr_test (SINGLE_TEST *test_data, int number, int converter, int verbose, double *conversion_rate)
{	static float data [BUFFER_LEN + 1] ;
	static float output [MAX_SPEC_LEN] ;

	SRC_STATE	*src_state ;
	SRC_DATA	src_data ;

	clock_t start_clock, clock_time ;

	double		output_peak, snr ;
	int 		k, output_len, input_len, error ;

	if (verbose != 0)
	{	printf ("\tSignal-to-Noise Ratio Test %d.\n"
				"\t=====================================\n", number) ;
		printf ("\tFrequencies : [ ") ;
		for (k = 0 ; k < test_data->freq_count ; k++)
			printf ("%6.4f ", test_data->freqs [k]) ;

		printf ("]\n\tSRC Ratio   : %8.4f\n", test_data->src_ratio) ;
		}
	else
	{	printf ("\tSignal-to-Noise Ratio Test %d : ", number) ;
		fflush (stdout) ;
		} ;

	/* Set up the output array. */
	if (test_data->src_ratio >= 1.0)
	{	output_len = MAX_SPEC_LEN ;
		input_len = (int) ceil (MAX_SPEC_LEN / test_data->src_ratio) ;
		if (input_len > BUFFER_LEN)
			input_len = BUFFER_LEN ;
		}
	else
	{	input_len = BUFFER_LEN ;
		output_len = (int) ceil (BUFFER_LEN * test_data->src_ratio) ;
		output_len &= ((-1) << 4) ;
		if (output_len > MAX_SPEC_LEN)
			output_len = MAX_SPEC_LEN ;
		input_len = (int) ceil (output_len / test_data->src_ratio) ;
		} ;

	memset (output, 0, sizeof (output)) ;

	/* Generate input data array. */
	gen_windowed_sines (data, input_len, test_data->freqs, test_data->freq_count) ;

	/* Perform sample rate conversion. */
	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) ;
		} ;

	src_data.end_of_input = 1 ; /* Only one buffer worth of input. */

	src_data.data_in = data ;
	src_data.input_frames = input_len ;

	src_data.src_ratio = test_data->src_ratio ;

	src_data.data_out = output ;
	src_data.output_frames = output_len ;

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

	clock_time = clock () - start_clock ;

	src_state = src_delete (src_state) ;

	if (clock_time <= 0)
		clock_time = 1 ;

	*conversion_rate = (1.0 * output_len * CLOCKS_PER_SEC) / clock_time ;
	if (test_data->src_ratio < 1.0)
		*conversion_rate /= test_data->src_ratio ;

	if (verbose != 0)
	{	printf ("\tOutput Rate :   %.0f samples/sec\n", *conversion_rate) ;

		printf ("\tOutput Len  :   %ld\n", src_data.output_frames_gen) ;
		} ;

	if (abs (src_data.output_frames_gen - output_len) > 4)
	{	printf ("\n\nLine %d : output data length should be %d.\n\n", __LINE__, output_len) ;
		exit (1) ;
		} ;

	/* Check output peak. */
	output_peak = find_peak (output, src_data.output_frames_gen) ;

	if (verbose != 0)
		printf ("\tOutput Peak :   %6.4f\n", output_peak) ;

	if (fabs (output_peak - test_data->peak_value) > 0.01)
	{	printf ("\n\nLine %d : output peak (%6.4f) should be %6.4f\n\n", __LINE__, output_peak, test_data->peak_value) ;
		save_oct_data ("snr_test.dat", data, BUFFER_LEN, output, output_len) ;
		exit (1) ;
		} ;

	/* Calculate signal-to-noise ratio. */
	snr = calculate_snr (output, src_data.output_frames_gen) ;

	if (snr < 0.0)
	{	/* An error occurred. */
		save_oct_data ("snr_test.dat", data, BUFFER_LEN, output, src_data.output_frames_gen) ;
		exit (1) ;
		} ;

	if (verbose != 0)
		printf ("\tSNR Ratio   :   %.2f dB\n", snr) ;

	if (snr < test_data->snr)
	{	printf ("\n\nLine %d : SNR (%5.2f) should be > %6.2f dB\n\n", __LINE__, snr, test_data->snr) ;
		exit (1) ;
		} ;

	if (verbose != 0)
		puts ("\t-------------------------------------\n\tPass\n") ;
	else
		puts ("Pass") ;

	return snr ;
} /* snr_test */
Exemplo n.º 18
0
Resampler::~Resampler()
{
    src_delete(src_state_);
}
Exemplo n.º 19
0
float* ph_readaudio2(const char *filename, int sr, float *sigbuf, int &buflen, const float nbsecs) {

    long orig_sr;
    float *inbuffer = NULL;
    unsigned int inbufferlength;
    buflen = 0;

    const char *suffix = strrchr(filename, '.');
    if (suffix == NULL) return NULL;
    if (!strcasecmp(suffix+1, "mp3")) {
#ifdef HAVE_LIBMPG123
        inbuffer = readaudio_mp3(filename, &orig_sr, nbsecs, &inbufferlength);
#endif /* HAVE_LIBMPG123 */
    } else {
        inbuffer = readaudio_snd(filename, &orig_sr, nbsecs, &inbufferlength);
    }

    if (inbuffer == NULL) {
        return NULL;
    }

    /* resample float array */
    /* set desired sr ratio */
    double sr_ratio = (double)(sr)/(double)orig_sr;
    if (src_is_valid_ratio(sr_ratio) == 0) {
        free(inbuffer);
        return NULL;
    }

    /* allocate output buffer for conversion */
    unsigned int outbufferlength = sr_ratio*inbufferlength;
    float *outbuffer = (float*)malloc(outbufferlength*sizeof(float));
    if (!outbuffer) {
        free(inbuffer);
        return NULL;
    }

    int error;
    SRC_STATE *src_state = src_new(SRC_LINEAR, 1, &error);
    if (!src_state) {
        free(inbuffer);
        free(outbuffer);
        return NULL;
    }

    SRC_DATA src_data;
    src_data.data_in = inbuffer;
    src_data.data_out = outbuffer;
    src_data.input_frames = inbufferlength;
    src_data.output_frames = outbufferlength;
    src_data.end_of_input = SF_TRUE;
    src_data.src_ratio = sr_ratio;

    /* sample rate conversion */
    if (error = src_process(src_state, &src_data)) {
        free(inbuffer);
        free(outbuffer);
        src_delete(src_state);
        return NULL;
    }

    buflen = src_data.output_frames;

    src_delete(src_state);
    free(inbuffer);

    return outbuffer;
}
Exemplo n.º 20
0
static void free_src(void) {
    src_delete(src);
    src = NULL;
}
Exemplo n.º 21
0
AUD_SRCResampleReader::~AUD_SRCResampleReader()
{
	src_delete(m_src);
}
Exemplo n.º 22
0
//***************************************************************************
Kwave::RateConverter::~RateConverter()
{
    if (m_converter) src_delete(m_converter);
}
Exemplo n.º 23
0
/* All and mighty connection handler. */
static void* rsd_thread(void *thread_data)
{
   connection_t conn;
   void *data = NULL;
   wav_header_t w;
   wav_header_t w_orig;
   int resample = 0;
   int rc, written;
   void *buffer = NULL;
#ifdef HAVE_SAMPLERATE
   SRC_STATE *resample_state = NULL;
#else
   resampler_t *resample_state = NULL;
#endif
   float *resample_buffer = NULL;
   resample_cb_state_t cb_data;

   connection_t *temp_conn = thread_data;
   conn.socket = temp_conn->socket;
   conn.ctl_socket = temp_conn->ctl_socket;
   conn.serv_ptr = 0;
   conn.rate_ratio = 1.0;
   conn.identity[0] = '\0';
   free(temp_conn);

   if ( debug )
      log_printf("Connection accepted, awaiting WAV header data ...\n");

   /* Firstly, get the wave header with stream settings. */
   rc = get_wav_header(conn, &w);
   if ( rc == -1 )
   {
      close(conn.socket);
      close(conn.ctl_socket);
      log_printf("Couldn't read WAV header... Disconnecting.\n");
      pthread_exit(NULL);
   }
   memcpy(&w_orig, &w, sizeof(wav_header_t));

   if ( resample_freq > 0 && resample_freq != (int)w.sampleRate )
   {
      w.sampleRate = resample_freq;
      w.bitsPerSample = w_orig.bitsPerSample == 32 ? 32 : 16;
      if (w_orig.bitsPerSample == 32)
         w.rsd_format = (is_little_endian()) ? RSD_S32_LE : RSD_S32_BE;
      else
         w.rsd_format = (is_little_endian()) ? RSD_S16_LE : RSD_S16_BE;
      resample = 1;
      conn.rate_ratio = (float)w.sampleRate * w.bitsPerSample / ((float)w_orig.sampleRate * w_orig.bitsPerSample);
   }

   if ( debug )
   {
      log_printf("Successfully got WAV header ...\n");
      pheader(&w_orig);
      if ( resample )
      {
         log_printf("Resamples to:\n");
         pheader(&w);
      }
   }

   if ( debug )
      log_printf("Initializing %s ...\n", backend->backend);

   /* Sets up backend */
   if ( backend->init(&data) < 0 )
   {
      log_printf("Failed to initialize %s ...\n", backend->backend);
      goto rsd_exit;
   }

   /* Opens device with settings. */
   if ( backend->open(data, &w) < 0 )
   {
      log_printf("Failed to open audio driver ...\n");
      goto rsd_exit;
   }

   backend_info_t backend_info; 
   memset(&backend_info, 0, sizeof(backend_info));
   backend->get_backend_info(data, &backend_info);
   if ( backend_info.chunk_size == 0 )
   {
      log_printf("Couldn't get backend info ...\n");
      goto rsd_exit;
   }

   if ( backend_info.resample )
   {
      resample = 1;
      w.sampleRate = w.sampleRate * backend_info.ratio;
      conn.rate_ratio = backend_info.ratio;

      w.bitsPerSample = w_orig.bitsPerSample == 32 ? 32 : 16;
      if (w_orig.bitsPerSample == 32)
         w.rsd_format = (is_little_endian()) ? RSD_S32_LE : RSD_S32_BE;
      else
         w.rsd_format = (is_little_endian()) ? RSD_S16_LE : RSD_S16_BE;
   }

   size_t size = backend_info.chunk_size;
   size_t read_size = size;

   size_t buffer_size = (read_size > size) ? read_size : size;
   buffer = malloc(buffer_size);
   if ( buffer == NULL )
   {
      log_printf("Could not allocate memory for buffer.");
      goto rsd_exit;
   }

   if ( resample )
   {
      resample_buffer = malloc(BYTES_TO_SAMPLES(buffer_size, w.rsd_format) * sizeof(float));
      if ( resample_buffer == NULL )
      {
         log_printf("Could not allocate memory for buffer.");
         goto rsd_exit;
      }

      cb_data.format = w_orig.rsd_format;
      cb_data.data = data;
      cb_data.conn = &conn;
      cb_data.framesize = w_orig.numChannels * rsnd_format_to_bytes(w_orig.rsd_format);

#ifdef HAVE_SAMPLERATE
      int err;
      resample_state = src_callback_new(resample_callback, src_converter, w.numChannels, &err, &cb_data);
#else
      resample_state = resampler_new(resample_callback, (float)w.sampleRate/w_orig.sampleRate, w.numChannels, &cb_data);
#endif
      if ( resample_state == NULL )
      {
         log_printf("Could not initialize resampler.");
         goto rsd_exit;
      }
   }

#define MAX_TCP_BUFSIZ (1 << 14)

   // We only bother with setting buffer size if we're doing TCP.
   if ( rsd_conn_type == RSD_CONN_TCP )
   {
      int flag = 1;
      int bufsiz = backend_info.chunk_size * 32;
      if (bufsiz > MAX_TCP_BUFSIZ)
         bufsiz = MAX_TCP_BUFSIZ;

      setsockopt(conn.socket, SOL_SOCKET, SO_RCVBUF, CONST_CAST &bufsiz, sizeof(int));

      if ( conn.ctl_socket )
      {
         setsockopt(conn.ctl_socket, SOL_SOCKET, SO_RCVBUF, CONST_CAST &bufsiz, sizeof(int));
         setsockopt(conn.ctl_socket, SOL_SOCKET, SO_SNDBUF, CONST_CAST &bufsiz, sizeof(int));
         setsockopt(conn.ctl_socket, IPPROTO_TCP, TCP_NODELAY, CONST_CAST &flag, sizeof(int));
      }

      setsockopt(conn.socket, IPPROTO_TCP, TCP_NODELAY, CONST_CAST &flag, sizeof(int));
   }

   /* Now we can send backend info to client. */
   if ( send_backend_info(conn, &backend_info) < 0 )
   {
      log_printf("Failed to send backend info ...\n");
      goto rsd_exit;
   }

   if ( debug )
      log_printf("Initializing of %s successful ...\n", backend->backend);

   if ( debug )
   {
      if ( resample )
      {
         log_printf("Resampling active. %d Hz --> %d Hz ", (int)w_orig.sampleRate, (int)w.sampleRate);
#ifdef HAVE_SAMPLERATE
         log_printf("(libsamplerate)\n");
#else
         log_printf("(internal quadratic resampler)\n");
#endif
      }
   }

   /* Recieve data, write to sound card. Rinse, repeat :') */
   for(;;)
   {
      if ( strlen(conn.identity) > 0 && verbose )
      {
         log_printf(" :: %s\n", conn.identity);
         conn.identity[0] = '\0';
      }

      if ( resample )
      {
#ifdef HAVE_SAMPLERATE
         rc = src_callback_read(resample_state, (double)w.sampleRate/(double)w_orig.sampleRate, BYTES_TO_SAMPLES(size, w.rsd_format)/w.numChannels, resample_buffer);
         if (rsnd_format_to_bytes(w.rsd_format) == 4)
            src_float_to_int_array(resample_buffer, buffer, BYTES_TO_SAMPLES(size, w.rsd_format));
         else
            src_float_to_short_array(resample_buffer, buffer, BYTES_TO_SAMPLES(size, w.rsd_format));
#else
         rc = resampler_cb_read(resample_state, BYTES_TO_SAMPLES(size, w.rsd_format)/w.numChannels, resample_buffer);
         if (rsnd_format_to_bytes(w.rsd_format) == 4)
            resampler_float_to_s32(buffer, resample_buffer, BYTES_TO_SAMPLES(size, w.rsd_format));
         else
            resampler_float_to_s16(buffer, resample_buffer, BYTES_TO_SAMPLES(size, w.rsd_format));
#endif
      }
      else
         rc = receive_data(data, &conn, buffer, read_size);

      if ( rc <= 0 )
      {
         if ( debug )
            log_printf("Client closed connection.\n");
         goto rsd_exit;
      }

      for ( written = 0; written < (int)size; )
      {
         rc = backend->write(data, (const char*)buffer + written, size - written);
         if ( rc == 0 )
            goto rsd_exit;

         written += rc;
      }
   }

   /* Cleanup */
rsd_exit:
   if ( debug )
      log_printf("Closed connection.\n\n");
#ifdef _WIN32
#undef close
#endif
   backend->close(data);
#ifdef _WIN32
#define close(x) closesocket(x)
#endif
   free(buffer);
   close(conn.socket);
   if (conn.ctl_socket)
      close(conn.ctl_socket);

   if (resample_state)
   {
#ifdef HAVE_SAMPLERATE
      src_delete(resample_state);
#else
      resampler_free(resample_state);
#endif
   }
   free(resample_buffer);
   pthread_exit(NULL);
}