コード例 #1
0
ファイル: wave.cpp プロジェクト: DomiLou/giada
int Wave::resample(int quality, int newRate)
{
	float ratio = newRate / (float) inHeader.samplerate;
	int newSize = ceil(size * ratio);
	if (newSize % 2 != 0)   // libsndfile goes crazy with odd size in case of saving
		newSize++;

	float *tmp = (float *) malloc(newSize * sizeof(float));
	if (!tmp) {
		gLog("[wave] unable to allocate memory for resampling\n");
		return -1;
	}

	SRC_DATA src_data;
	src_data.data_in       = data;
	src_data.input_frames  = size/2;     // in frames, i.e. /2 (stereo)
	src_data.data_out      = tmp;
	src_data.output_frames = newSize/2;  // in frames, i.e. /2 (stereo)
	src_data.src_ratio     = ratio;

	gLog("[wave] resampling: new size=%d (%d frames)\n", newSize, newSize/2);

	int ret = src_simple(&src_data, quality, 2);
	if (ret != 0) {
		gLog("[wave] resampling error: %s\n", src_strerror(ret));
		return 0;
	}

	free(data);
	data = tmp;
	size = newSize;
	inHeader.samplerate = newRate;
	return 1;
}
コード例 #2
0
ファイル: snr_bw_test.c プロジェクト: CoolOppo/audacity
static double
find_attenuation (double freq, int converter, int verbose)
{	static float input	[BUFFER_LEN] ;
	static float output [2 * BUFFER_LEN] ;

	SRC_DATA	src_data ;
	double 		output_peak ;
	int			error ;

	gen_windowed_sines (input, BUFFER_LEN, &freq, 1) ;

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

	src_data.data_in = input ;
	src_data.input_frames = BUFFER_LEN ;

	src_data.src_ratio = 1.999 ;

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

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

	output_peak = find_peak (output, ARRAY_LEN (output)) ;

	if (verbose)
		printf ("\tFreq : %6f   InPeak : %6f    OutPeak : %6f   Atten : %6.2f dB\n",
				freq, 1.0, output_peak, 20.0 * log10 (1.0 / output_peak)) ;

	return 20.0 * log10 (1.0 / output_peak) ;
} /* find_attenuation */
コード例 #3
0
ファイル: resample.cpp プロジェクト: anthonycouret/essentia
void Resample::compute() {
  const std::vector<Real>& signal = _signal.get();
  std::vector<Real>& resampled = _resampled.get();

  if (_factor == 1.0) {
    resampled = signal;
    return;
  }

  if (signal.empty()) return;

  SRC_DATA src;
  src.input_frames = (long)signal.size();
  src.data_in = const_cast<float*>(&(signal[0]));

  // add some samples to make sure we don't crash in a stupid way...
  src.output_frames = (long)((double)signal.size()*_factor + 100.0);
  resampled.resize(src.output_frames);
  src.data_out = &(resampled[0]);

  src.src_ratio = _factor;

  // do the conversion
  int error = src_simple(&src, _quality, 1);

  if (error) throw EssentiaException("Resample: Error in resampling: ", src_strerror(error));

  resampled.resize(src.output_frames_gen);
}
コード例 #4
0
ファイル: file.c プロジェクト: JamieBeverley/Dirt
void fix_samplerate (t_sample *sample) {
  SRC_DATA data;
  int max_output_frames;
  int channels = sample->info->channels;

  //printf("start frames: %d\n", sample->info->frames);
  if (sample->info->samplerate == g_samplerate) {
    return;
  }
  data.src_ratio = (float) g_samplerate / (float) sample->info->samplerate;
  //printf("ratio: %d / %d = %f\n", sample->info->samplerate, samplerate, data.src_ratio);
  max_output_frames = sample->info->frames * data.src_ratio + 32;

  data.data_in = sample->items;
  data.input_frames = sample->info->frames;

  data.data_out = (float *) calloc(1, sizeof(float)
                                      * max_output_frames
                                      * channels
                                   );
  data.output_frames = max_output_frames;

  src_simple(&data, SRC_SINC_BEST_QUALITY, channels);

  if (sample->items) free(sample->items);
  sample->items = data.data_out;
  sample->info->samplerate = g_samplerate;
  sample->info->frames = data.output_frames_gen;
  //printf("end samplerate: %d frames: %d\n", (int) sample->info->samplerate, sample->info->frames);
}
コード例 #5
0
ファイル: config.cpp プロジェクト: reuk/wayverb
util::aligned::vector<float> adjust_sampling_rate(const float* data,
                                                  size_t size,
                                                  double in_sr,
                                                  double out_sr) {
    if (!(in_sr && out_sr)) {
        throw std::runtime_error{
                "Sample rate of 0 gives few hints about how to proceed."};
    }
    const auto ratio = out_sr / in_sr;
    util::aligned::vector<float> out_signal(ratio * size);
    SRC_DATA sample_rate_info{data,
                              out_signal.data(),
                              static_cast<long>(size),
                              static_cast<long>(out_signal.size()),
                              0,
                              0,
                              0,
                              out_sr / in_sr};
    src_simple(&sample_rate_info, SRC_SINC_BEST_QUALITY, 1);

    //  Correct output level.
    const auto volume_scale = 1 / ratio;
    for (auto& i : out_signal) {
        i *= volume_scale;
    }

    return out_signal;
}
コード例 #6
0
ファイル: termination_test.c プロジェクト: AugRob/ssr
static void
simple_test (int converter)
{
	int ilen = 199030, olen = 1000, error ;

	{
		float in [ilen] ;
		float out [olen] ;
		double ratio = (1.0 * olen) / ilen ;
		SRC_DATA src_data =
		{	in, out,
			ilen, olen,
			0, 0, 0,
			ratio
		} ;

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

    return ;
} /* simple_test */
コード例 #7
0
ファイル: BTrack.c プロジェクト: zbanks/BTrack
static void resampleOnsetDetectionFunction(struct btrack * bt) {
	float output[512];
    float * input = malloc(bt->onsetDFBufferSize * sizeof(float));
    BTRACK_ASSERT(input);
    
    for (int i = 0;i < bt->onsetDFBufferSize;i++) {
        input[i] = (float) bt->onsetDF[i];
    }
		
	double src_ratio = 512.0/((double) bt->onsetDFBufferSize);
	int BUFFER_LEN = bt->onsetDFBufferSize;
	int output_len;
	SRC_DATA	src_data ;
	
	//output_len = (int) floor (((double) BUFFER_LEN) * src_ratio) ;
	output_len = 512;
	
	src_data.data_in = input;
	src_data.input_frames = BUFFER_LEN;
	
	src_data.src_ratio = src_ratio;
	
	src_data.data_out = output;
	src_data.output_frames = output_len;
	
	src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1);
			
	for (int i = 0;i < output_len;i++) {
		bt->resampledOnsetDF[i] = (double) src_data.data_out[i];
	}
    free(input);
}
コード例 #8
0
static void
simple_test (int converter, double src_ratio)
{	static float input [BUFFER_LEN], output [BUFFER_LEN] ;

	SRC_DATA	src_data ;

	int input_len, output_len, error, terminate ;

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

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

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

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

	memset (&src_data, 0, sizeof (src_data)) ;

	src_data.data_in = input ;
	src_data.input_frames = input_len ;

	src_data.src_ratio = src_ratio ;

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

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

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

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

	puts ("ok") ;

	return ;
} /* simple_test */
コード例 #9
0
ファイル: resample.cpp プロジェクト: lenalebt/libmusic
 bool Resampler22kHzMono::resample(uint32_t fromSampleRate, int16_t** samplePtr, unsigned int& sampleCount, unsigned int channelCount) const
 {
     //first convert to mono - we do not need stereo or more channels.
     unsigned int frameCount = sampleCount/channelCount;
     int16_t* monoSamples = new int16_t[frameCount];
     if (!monoSamples)   //failed to get memory
         return false;
     
     int16_t* samples = *samplePtr;
     for (unsigned int i = 0; i < frameCount; i++)
     {
         int32_t tmpVal = 0;
         int offset = channelCount * i;
         for (unsigned int j = 0; j < channelCount; j++)
         {
             tmpVal += samples[offset + j];
         }
         monoSamples[i] = tmpVal / channelCount;
     }
     //should have mono samples now. we can discard the old samples.
     delete[] samples;
     samples = NULL;
     sampleCount = frameCount;
     *samplePtr = monoSamples;
     
     SRC_DATA srcdata;
     
     srcdata.data_in = new float[sampleCount];
     src_short_to_float_array(*samplePtr, srcdata.data_in, sampleCount);
     delete *samplePtr;
     
     srcdata.input_frames = sampleCount;
     
     srcdata.output_frames = int(sampleCount * 22050.0 / double(fromSampleRate)) + 1;
     srcdata.data_out = new float[srcdata.output_frames];
     
     srcdata.src_ratio = 22050.0 / double(fromSampleRate);
     
     //do some fast conversion at reasonable quality
     if (src_simple(&srcdata, SRC_SINC_FASTEST, 1) != 0)
         return false;
     
     delete srcdata.data_in;
     
     *samplePtr = new int16_t[srcdata.output_frames];
     
     src_float_to_short_array(srcdata.data_out, *samplePtr, srcdata.output_frames);
     delete srcdata.data_out;
     
     sampleCount = srcdata.output_frames;
     
     return true;
 }
コード例 #10
0
void AudioBuffer::convert_rate(AudioBuffer &_dest, unsigned _frames_count, SRC_STATE *_SRC)
{
	AudioSpec destspec{AUDIO_FORMAT_F32, m_spec.channels, _dest.rate()};
	if(m_spec.format != AUDIO_FORMAT_F32 || _dest.spec() != destspec) {
		throw std::logic_error("unsupported format");
	}
	_frames_count = std::min(frames(),_frames_count);
	double rate_ratio = double(destspec.rate)/double(m_spec.rate);
	unsigned out_frames = unsigned(ceil(double(_frames_count) * rate_ratio));
	if(out_frames==0) {
		return;
	}

	unsigned destpos = _dest.samples();
	unsigned destframes = _dest.frames();

	_dest.resize_frames(_dest.frames()+out_frames);

#if HAVE_LIBSAMPLERATE
	SRC_DATA srcdata;
	srcdata.data_in = &at<float>(0);
	srcdata.data_out = &_dest.at<float>(destpos);
	srcdata.input_frames = _frames_count;
	srcdata.output_frames = out_frames;
	srcdata.src_ratio = rate_ratio;
	int srcresult;
	if(_SRC != nullptr) {
		srcdata.end_of_input = 0;
		srcresult = src_process(_SRC, &srcdata);
	} else {
		srcdata.end_of_input = 1;
		srcresult = src_simple(&srcdata, SRC_SINC_BEST_QUALITY, destspec.channels) ;
	}
	if(srcresult != 0) {
		throw std::runtime_error(std::string("error resampling: ") + src_strerror(srcresult));
	}
	assert(srcdata.output_frames_gen>=0 && srcdata.output_frames_gen<=out_frames);
	if(srcdata.output_frames_gen != out_frames) {
		_dest.resize_frames(destframes + srcdata.output_frames_gen);
	}
	PDEBUGF(LOG_V2, LOG_MIXER, "convert rate: f-in: %d, f-out: %d, gen: %d\n",
			_frames_count, out_frames, srcdata.output_frames_gen);
#else
	for(unsigned i=destpos; i<_dest.samples(); ++i) {
		_dest.operator[]<float>(i) = 0.f;
	}
#endif
}
コード例 #11
0
ファイル: sample.c プロジェクト: jphaenlin/Petri-Foo
static float* resample(float* samples, int rate, SF_INFO* sfinfo)
{
    double ratio;
    int err;
    SRC_DATA src;
    float* tmp;

    ratio = rate / (sfinfo->samplerate * 1.0);

    debug("Resampling from %d to %d\n", rate, sfinfo->samplerate);

    src.src_ratio = ratio;
    src.data_in = samples;
    src.input_frames = sfinfo->frames;
    src.output_frames = sfinfo->frames * ratio;

    if (src.output_frames >= MAX_SAMPLE_FRAMES)
    {
        pf_error(PF_ERR_SAMPLE_RESAMPLE_MAX_FRAMES);
        return 0;
    }

    tmp = malloc(sizeof(float)
                * sfinfo->frames * sfinfo->channels * ratio);
    if (!tmp)
    {
        pf_error(PF_ERR_SAMPLE_RESAMPLE_ALLOC);
        return 0;
    }

    src.data_out = tmp;

    err = src_simple(&src, SRC_SINC_BEST_QUALITY, sfinfo->channels);
    if (err)
    {
        pf_error(PF_ERR_SAMPLE_SRC_SIMPLE);
        free(tmp);
        return 0;
    }

    sfinfo->frames = src.output_frames;

    return tmp;
}
コード例 #12
0
ファイル: downsample_test.c プロジェクト: erikd/libsamplerate
static void
downsample_test (int converter)
{	static float in [1000], out [10] ;
	SRC_DATA data ;

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

	data.src_ratio = 1.0 / 255.0 ;
	data.input_frames = ARRAY_LEN (in) ;
	data.output_frames = ARRAY_LEN (out) ;
	data.data_in = in ;
	data.data_out = out ;

	if (src_simple (&data, converter, 1))
	{	puts ("src_simple failed.") ;
		exit (1) ;
		} ;

	puts ("ok") ;
} /* downsample_test */
コード例 #13
0
ファイル: pv-complex.c プロジェクト: EQ4/waonc
/* resample pv->[rl]_out[i] for i = 0 to pv->hop_syn
 *       to [left,right][i] for i = 0 to pv->hop_res
 * INPUT
 * OUTPUT
 */
void
pv_complex_resample (struct pv_complex * pv,
                     double * left, double * right)
{
   /* samplerate conversion */
   SRC_DATA srdata;
   static float * fl_in  = NULL;
   static float * fl_out = NULL;
   static int hop_syn0 = 0;
   static int hop_res0 = 0;
   int i;
   int status;
   if (fl_in == NULL)
   {
      fl_in  = (float *)malloc (sizeof (float) * 2 * pv->hop_syn);
      fl_out = (float *)malloc (sizeof (float) * 2 * pv->hop_res);
      CHECK_MALLOC (fl_in,  "pv_complex_resample");
      CHECK_MALLOC (fl_out, "pv_complex_resample");
      hop_syn0 = pv->hop_syn;
      hop_res0 = pv->hop_res;
   }
   else
   {
      if (hop_syn0 < pv->hop_syn)
      {
         fl_in = (float *)realloc (fl_in, sizeof (float) * 2 * pv->hop_syn);
         CHECK_MALLOC (fl_in,  "pv_complex_resample");
         hop_syn0 = pv->hop_syn;
      }
      if (hop_res0 < pv->hop_res)
      {
         fl_out =
            (float *)realloc (fl_out, sizeof (float) * 2 * pv->hop_res);
         CHECK_MALLOC (fl_out, "pv_complex_resample");
         hop_res0 = pv->hop_res;
      }
   }

   srdata.input_frames  = pv->hop_syn;
   srdata.output_frames = pv->hop_res;
   srdata.src_ratio = (double)(pv->hop_res) / (double)(pv->hop_syn);
   srdata.data_in  = fl_in;
   srdata.data_out = fl_out;

   /* samplerate conversion (time fixed) */

   for (i = 0; i < pv->hop_syn; i ++)
   {
      fl_in [i * 2 + 0] = (float)(pv->l_out [i]);
      fl_in [i * 2 + 1] = (float)(pv->r_out [i]);
   }

   /*status = src_simple (&srdata, SRC_SINC_BEST_QUALITY, 2); */

   status = src_simple (&srdata, SRC_SINC_FASTEST, 2);

   /* this works better */

   if (status != 0)
   {
      fprintf (stderr, "fail to samplerate conversion\n");
      exit (1);
   }

   for (i = 0; i < pv->hop_res; i ++)
   {
      left [i]  = (double)(fl_out [i * 2 + 0]);
      right [i] = (double)(fl_out [i * 2 + 1]);
   }
}
コード例 #14
0
static void
simple_test (int converter, int channel_count, double target_snr)
{	SRC_DATA	src_data ;

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

	printf ("\t%-22s (%d channel%c) ............. ", "simple_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) ;

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

	src_data.data_in = input_interleaved ;
	src_data.input_frames = frames ;

	src_data.data_out = output_interleaved ;
	src_data.output_frames = frames ;

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

	if (fabs (src_data.output_frames_gen - src_data.src_ratio * src_data.input_frames) > 2)
	{	printf ("\n\nLine %d : bad output data length %ld should be %d.\n", __LINE__,
					src_data.output_frames_gen, (int) floor (src_data.src_ratio * src_data.input_frames)) ;
		printf ("\tsrc_ratio  : %.4f\n", src_data.src_ratio) ;
		printf ("\tinput_len  : %ld\n", src_data.input_frames) ;
		printf ("\toutput_len : %ld\n\n", src_data.output_frames_gen) ;
		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 ;
} /* simple_test */
コード例 #15
0
ファイル: termination_test.c プロジェクト: AugRob/ssr
static void
init_term_test (int converter, double src_ratio)
{	static float input [SHORT_BUFFER_LEN], output [SHORT_BUFFER_LEN] ;

	SRC_DATA	src_data ;

	int k, input_len, output_len, error, terminate ;

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

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

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

	for (k = 0 ; k < ARRAY_LEN (input) ; k++)
		input [k] = 1.0 ;

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

	src_data.data_in = input ;
	src_data.input_frames = input_len ;

	src_data.src_ratio = src_ratio ;

	src_data.data_out = output ;
	src_data.output_frames = SHORT_BUFFER_LEN ;

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

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

	if (fabs (src_ratio * input_len - src_data.output_frames_gen) > terminate)
	{	printf ("\n\nLine %d : Bad output frame count.\n\n", __LINE__) ;
		printf ("\tterminate             : %d\n", terminate) ;
		printf ("\tsrc_ratio             : %.4f\n", src_ratio) ;
		printf ("\tinput_len             : %d\n"
				"\tinput_len * src_ratio : %f\n", input_len, input_len * src_ratio) ;
		printf ("\toutput_frames_gen     : %ld\n\n", src_data.output_frames_gen) ;
		exit (1) ;
		} ;

	if (abs (src_data.input_frames_used - input_len) > 1)
	{	printf ("\n\nLine %d : input_frames_used should be %d, is %ld.\n\n",
					 __LINE__, input_len, src_data.input_frames_used) ;
		printf ("\tsrc_ratio  : %.4f\n", src_ratio) ;
		printf ("\tinput_len  : %d\n\tinput_used : %ld\n\n", input_len, src_data.input_frames_used) ;
		exit (1) ;
		} ;

	if (fabs (output [0]) < 0.1)
	{	printf ("\n\nLine %d : First output sample is bad.\n\n", __LINE__) ;
		printf ("\toutput [0] == %f\n\n", output [0]) ;
		exit (1) ;
		}

	puts ("ok") ;

	return ;
} /* init_term_test */
コード例 #16
0
ファイル: video_layer.cpp プロジェクト: dewn49/FreeJ
void *VideoLayer::feed() {
  int got_picture=0;
  int len1=0 ;
  int ret=0;
  bool got_it=false;

  double now = get_master_clock();


  if(paused)
    return rgba_picture->data[0];

  /**
   * follow user video loop
   */
  if(mark_in!=NO_MARK && mark_out!=NO_MARK && seekable) {
    if (now >= mark_out)
      seek((int64_t)mark_in * AV_TIME_BASE);
  }
  
  // operate seek if was requested
  if(to_seek>=0) {
    seek(to_seek);
    to_seek = -1;
  }
    
  got_it=false;
  
  while (!got_it) {
    
    
    if(packet_len<=0) {
      /**
       * Read one packet from the media and put it in pkt
       */
      while(1) {
#ifdef DEBUG
	func("av_read_frame ...");
#endif
	ret = av_read_frame(avformat_context, &pkt);

#ifdef DEBUG
	if(pkt.stream_index == video_index)
	  std::cout << "video read packet";
	else if(pkt.stream_index == audio_index)
	  std::cout << "audio read packet";
	std::cout << " pkt.data=" << pkt.data;
	std::cout << " pkt.size=" << pkt.size;
	std::cout << " pkt.pts/dts=" << pkt.pts << "/" << pkt.dts << std::endl;
	std::cout << "pkt.duration=" << pkt.duration;
	std::cout << " avformat_context->start_time=" << avformat_context->start_time;
	std::cout << " avformat_context->duration=" << avformat_context->duration/AV_TIME_BASE << std::endl;
	std::cout << "avformat_context->duration=" << avformat_context->duration << std::endl;
#endif
	
	/* TODO(shammash): this may be good for streams but breaks
	 * looping in files, needs fixing. */
	// 	      if(!pkt.duration) continue;
	
	// 	      if(!pkt.size || !pkt.data) {
	// 		return NULL;
	// 	      }
	
	
	/**
	 * check eof and loop
	 */
	if(ret!= 0) {	//does not enter if data are available
	  eos->notify();
	  //	  eos->dispatcher->do_jobs(); /// XXX hack hack hack
	  ret = seek(avformat_context->start_time);
	  if (ret < 0) {
	    error("VideoLayer::could not loop file");
	    return rgba_picture->data[0];
	  }
	  continue;
	} else if( (pkt.stream_index == video_index) 
		   || (pkt.stream_index == audio_index) )
	  break; /* exit loop */
      }
    } // loop break after a known index is found
    
    
    frame_number++;
	//std::cout << "frame_number :" << frame_number << std::endl;
    
    /**
     * Decode video
     */
    if(pkt.stream_index == video_index) {
      
      len1 = decode_video_packet(&got_picture);
      
      AVFrame *yuv_picture=&av_frame;
      if(len1<0) {
	//	  error("VideoLayer::Error while decoding frame");
	func("one frame only?");
	return NULL;
      }
      else if (len1 == 0) {
	packet_len=0;
	return NULL;
      }
      
      /**
       * We've found a picture
       */
      ptr += len1;
      packet_len -= len1;
      if (got_picture!=0) {
	got_it=true;
	avformat_stream=avformat_context->streams[video_index];
	
	/** Deinterlace input if requested */
	if(deinterlaced)
	  deinterlace((AVPicture *)yuv_picture);
	
#ifdef WITH_SWSCALE
	sws_scale(img_convert_ctx, yuv_picture->data, yuv_picture->linesize,
		  0, video_codec_ctx->height,
		  rgba_picture->data, rgba_picture->linesize);	  
#else
	/**
	 * yuv2rgb
	 */
	img_convert(rgba_picture, PIX_FMT_RGB32, (AVPicture *)yuv_picture,
		    video_codec_ctx->pix_fmt, 
		    //avformat_stream.codec->pix_fmt,
		    video_codec_ctx->width,
		    video_codec_ctx->height);
#endif
	// memcpy(frame_fifo.picture[fifo_position % FIFO_SIZE]->data[0],rgba_picture->data[0],geo.size);
	/* TODO move */
	if(fifo_position == FIFO_SIZE)
	  fifo_position=0;
	
	/* workaround since sws_scale conversion from YUV
	   returns an buffer RGBA with alpha set to 0x0  */
	{
	  register int bufsize = ( rgba_picture->linesize[0] * video_codec_ctx->height ) /4;
	  int32_t *pbuf =  (int32_t*)rgba_picture->data[0];
	  
	  for(; bufsize>0; bufsize--) {
	    *pbuf = (*pbuf | alpha_bitmask);
	    pbuf++;
	  }
	} 
	
	jmemcpy(frame_fifo.picture[fifo_position]->data[0],
		rgba_picture->data[0],
		rgba_picture->linesize[0] * video_codec_ctx->height);
	
	//			    avpicture_get_size(PIX_FMT_RGBA32, enc->width, enc->height));
	fifo_position++;
      }
    } // end video packet decoding
    

    ////////////////////////
    // audio packet decoding
    else if(pkt.stream_index == audio_index) {
      // XXX(shammash): audio decoding seems to depend on screen properties, so
      //                we skip decoding audio frames if there's no screen
      //  long unsigned int m_SampleRate = screen->m_SampleRate?*(screen->m_SampleRate):48000;
      //  ringbuffer_write(screen->audio, (const char*)audio_float_buf,  samples*sizeof(float));
      //  ... and so on ...
      if(use_audio && screen) {
	int data_size;
	len1 = decode_audio_packet(&data_size);
	if (len1 > 0)  {
	  int samples = data_size/sizeof(uint16_t);
	  long unsigned int m_SampleRate = screen->m_SampleRate?*(screen->m_SampleRate):48000;
	  double m_ResampleRatio = (double)(m_SampleRate)/(double)audio_samplerate; 
	  long unsigned max_buf = ceil(AVCODEC_MAX_AUDIO_FRAME_SIZE * m_ResampleRatio * audio_channels);

	  if (audio_resampled_buf_len < max_buf) {
		if (audio_resampled_buf) free (audio_resampled_buf);
		audio_resampled_buf = (float*) malloc(max_buf * sizeof(float));
		audio_resampled_buf_len = max_buf;
	  }

	  src_short_to_float_array ((const short*) audio_buf, audio_float_buf, samples);
	  if (m_ResampleRatio == 1.0) 
	  {
	    ringbuffer_write(screen->audio, (const char*)audio_float_buf,  samples*sizeof(float));
	    time_t *tm = (time_t *)malloc(sizeof(time_t));
	    time (tm);
// 	    std::cerr << "-- VL:" << asctime(localtime(tm));
	  } 
	  else 
	  {
	    src_short_to_float_array ((const short*) audio_buf, audio_float_buf, samples);

	    SRC_DATA src_data;
	    int offset = 0;

            do {
	      src_data.input_frames  = samples/audio_channels;
	      src_data.output_frames = audio_resampled_buf_len/audio_channels - offset;
	      src_data.end_of_input  = 0;
	      src_data.src_ratio     =  m_ResampleRatio;
	      src_data.input_frames_used = 0;
	      src_data.output_frames_gen = 0;
	      src_data.data_in       = audio_float_buf + offset; 
	      src_data.data_out      = audio_resampled_buf + offset;

	      src_simple (&src_data, SRC_SINC_MEDIUM_QUALITY, audio_channels) ;
	      ringbuffer_write(screen->audio,
			       (const char*)audio_resampled_buf,
			       src_data.output_frames_gen * audio_channels *sizeof(float));

	      offset += src_data.input_frames_used * audio_channels;
	      samples -= src_data.input_frames_used * audio_channels;

	      if (samples>0)
		warning("resampling left: %i < %i",
			src_data.input_frames_used, samples/audio_channels);

	    } while (samples > audio_channels);
	  }
	}
      }
    }
    
    av_free_packet(&pkt); /* sun's good. love's bad */
    
  } // end of while(!got_it)
  
  return frame_fifo.picture[fifo_position-1]->data[0];
}
コード例 #17
0
ファイル: i_sdlsound.c プロジェクト: twipley/chocolate-doom
static boolean ExpandSoundData_SRC(sfxinfo_t *sfxinfo,
                                   byte *data,
                                   int samplerate,
                                   int length)
{
    SRC_DATA src_data;
    uint32_t i, abuf_index=0, clipped=0;
    uint32_t alen;
    int retn;
    int16_t *expanded;
    Mix_Chunk *chunk;

    src_data.input_frames = length;
    src_data.data_in = malloc(length * sizeof(float));
    src_data.src_ratio = (double)mixer_freq / samplerate;

    // We include some extra space here in case of rounding-up.
    src_data.output_frames = src_data.src_ratio * length + (mixer_freq / 4);
    src_data.data_out = malloc(src_data.output_frames * sizeof(float));

    assert(src_data.data_in != NULL && src_data.data_out != NULL);

    // Convert input data to floats

    for (i=0; i<length; ++i)
    {
        // Unclear whether 128 should be interpreted as "zero" or whether a
        // symmetrical range should be assumed.  The following assumes a
        // symmetrical range.
        src_data.data_in[i] = data[i] / 127.5 - 1;
    }

    // Do the sound conversion

    retn = src_simple(&src_data, SRC_ConversionMode(), 1);
    assert(retn == 0);

    // Allocate the new chunk.

    alen = src_data.output_frames_gen * 4;

    chunk = AllocateSound(sfxinfo, src_data.output_frames_gen * 4);

    if (chunk == NULL)
    {
        return false;
    }

    expanded = (int16_t *) chunk->abuf;

    // Convert the result back into 16-bit integers.

    for (i=0; i<src_data.output_frames_gen; ++i)
    {
        // libsamplerate does not limit itself to the -1.0 .. 1.0 range on
        // output, so a multiplier less than INT16_MAX (32767) is required
        // to avoid overflows or clipping.  However, the smaller the
        // multiplier, the quieter the sound effects get, and the more you
        // have to turn down the music to keep it in balance.

        // 22265 is the largest multiplier that can be used to resample all
        // of the Vanilla DOOM sound effects to 48 kHz without clipping
        // using SRC_SINC_BEST_QUALITY.  It is close enough (only slightly
        // too conservative) for SRC_SINC_MEDIUM_QUALITY and
        // SRC_SINC_FASTEST.  PWADs with interestingly different sound
        // effects or target rates other than 48 kHz might still result in
        // clipping--I don't know if there's a limit to it.

        // As the number of clipped samples increases, the signal is
        // gradually overtaken by noise, with the loudest parts going first.
        // However, a moderate amount of clipping is often tolerated in the
        // quest for the loudest possible sound overall.  The results of
        // using INT16_MAX as the multiplier are not all that bad, but
        // artifacts are noticeable during the loudest parts.

        float cvtval_f =
            src_data.data_out[i] * libsamplerate_scale * INT16_MAX;
        int32_t cvtval_i = cvtval_f + (cvtval_f < 0 ? -0.5 : 0.5);

        // Asymmetrical sound worries me, so we won't use -32768.
        if (cvtval_i < -INT16_MAX)
        {
            cvtval_i = -INT16_MAX;
            ++clipped;
        }
        else if (cvtval_i > INT16_MAX)
        {
            cvtval_i = INT16_MAX;
            ++clipped;
        }

        // Left and right channels

        expanded[abuf_index++] = cvtval_i;
        expanded[abuf_index++] = cvtval_i;
    }

    free(src_data.data_in);
    free(src_data.data_out);

    if (clipped > 0)
    {
        fprintf(stderr, "Sound '%s': clipped %u samples (%0.2f %%)\n", 
                        sfxinfo->name, clipped,
                        400.0 * clipped / chunk->alen);
    }

    return true;
}
コード例 #18
0
static long
throughput_test (int converter, int channels, long best_throughput)
{	SRC_DATA src_data ;
	clock_t start_time, clock_time ;
	double duration ;
	long total_frames = 0, throughput ;
	int error ;

	printf ("    %-30s     %2d         ", src_get_name (converter), channels) ;
	fflush (stdout) ;

	src_data.data_in = input ;
	src_data.input_frames = ARRAY_LEN (input) / channels ;

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

	src_data.src_ratio = 0.99 ;

	sleep (2) ;

	start_time = clock () ;

	do
	{
		if ((error = src_simple (&src_data, converter, channels)) != 0)
		{	puts (src_strerror (error)) ;
			exit (1) ;
			} ;

		total_frames += src_data.output_frames_gen ;

		clock_time = clock () - start_time ;
		duration = (1.0 * clock_time) / CLOCKS_PER_SEC ;
	}
	while (duration < 5.0) ;

	if (src_data.input_frames_used != src_data.input_frames)
	{	printf ("\n\nLine %d : input frames used %ld should be %ld\n", __LINE__, src_data.input_frames_used, src_data.input_frames) ;
		exit (1) ;
		} ;

	if (fabs (src_data.src_ratio * src_data.input_frames_used - src_data.output_frames_gen) > 2)
	{	printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ;
		printf ("    input len  : %d\n", ARRAY_LEN (input) / channels) ;
		printf ("    output len : %ld (should be %g +/- 2)\n\n", src_data.output_frames_gen,
				floor (0.5 + src_data.src_ratio * src_data.input_frames_used)) ;
		exit (1) ;
		} ;

	throughput = lrint (floor (total_frames / duration)) ;

	if (best_throughput == 0)
	{	best_throughput = MAX (throughput, best_throughput) ;
		printf ("%5.2f      %10ld\n", duration, throughput) ;
		}
	else
	{	best_throughput = MAX (throughput, best_throughput) ;
		printf ("%5.2f      %10ld       %10ld\n", duration, throughput, best_throughput) ;
		}

	return best_throughput ;
} /* throughput_test */
コード例 #19
0
/* Sound data resampling */
static int raw_resample(char *fname, double ratio)
{
	int res = 0;
	FILE *fl;
	struct stat st;
	int in_size;
	short *in_buff, *out_buff;
	long in_frames, out_frames;
	float *inp, *outp;
	SRC_DATA rate_change;

	if ((fl = fopen(fname, "r")) == NULL) {
		ast_log(LOG_ERROR, "eSpeak: Failed to open file for resampling.\n");
		return -1;
	}
	if ((stat(fname, &st) == -1)) {
		ast_log(LOG_ERROR, "eSpeak: Failed to stat file for resampling.\n");
		fclose(fl);
		return -1;
	}
	in_size = st.st_size;
	if ((in_buff = ast_malloc(in_size)) == NULL) {
		fclose(fl);
		return -1;
	}
	if ((fread(in_buff, 1, in_size, fl) != (size_t)in_size)) {
		ast_log(LOG_ERROR, "eSpeak: Failed to read file for resampling.\n");
		fclose(fl);
		res = -1;
		goto CLEAN1;
	}
	fclose(fl);
	in_frames = in_size / 2;

	if ((inp = (float *)(ast_malloc(in_frames * sizeof(float)))) == NULL) {
		res = -1;
		goto CLEAN1;
	}
	src_short_to_float_array(in_buff, inp, in_size/sizeof(short));
	out_frames = (long)((double)in_frames * ratio);
	if ((outp = (float *)(ast_malloc(out_frames * sizeof(float)))) == NULL) {
		res = -1;
		goto CLEAN2;
	}
	rate_change.data_in = inp;
	rate_change.data_out = outp;
	rate_change.input_frames = in_frames;
	rate_change.output_frames = out_frames;
	rate_change.src_ratio = ratio;

	if ((res = src_simple(&rate_change, SRC_SINC_FASTEST, 1)) != 0) {
		ast_log(LOG_ERROR, "eSpeak: Failed to resample sound file '%s': '%s'\n",
				fname, src_strerror(res));
		res = -1;
		goto CLEAN3;
	}

	if ((out_buff = ast_malloc(out_frames*sizeof(float))) == NULL) {
		res = -1;
		goto CLEAN3;
	}
	src_float_to_short_array(rate_change.data_out, out_buff, out_frames);
	if ((fl = fopen(fname, "w+")) != NULL) {
		if ((fwrite(out_buff, 1, 2*out_frames, fl)) != (size_t)(2*out_frames)) {
			ast_log(LOG_ERROR, "eSpeak: Failed to write resampled output file.\n");
			res = -1;
		}
		fclose(fl);
	} else {
		ast_log(LOG_ERROR, "eSpeak: Failed to open output file for resampling.\n");
		res = -1;
	}
	ast_free(out_buff);
CLEAN3:
	ast_free(outp);
CLEAN2:
	ast_free(inp);
CLEAN1:
	ast_free(in_buff);
	return res;
}
コード例 #20
0
ファイル: audiofile.cpp プロジェクト: dyfet/sflphone
RawFile::RawFile(const std::string& name, sfl::AudioCodec *codec, unsigned int sampleRate)
    : AudioFile(name), audioCodec_(codec)
{
    if (filepath_.empty())
        throw AudioFileException("Unable to open audio file: filename is empty");

    std::fstream file;
    file.open(filepath_.c_str(), std::fstream::in);

    if (!file.is_open())
        throw AudioFileException("Unable to open audio file");

    file.seekg(0, std::ios::end);
    size_t length = file.tellg();
    file.seekg(0, std::ios::beg);

    std::vector<char> fileBuffer(length);
    file.read(&fileBuffer[0], length);
    file.close();

    const unsigned int frameSize = audioCodec_->getFrameSize();
    const unsigned int bitrate   = audioCodec_->getBitRate() * 1000 / 8;
    const unsigned int audioRate = audioCodec_->getClockRate();
    const unsigned int encFrameSize = frameSize * bitrate / audioRate;
    const unsigned int decodedSize = length * (frameSize / encFrameSize);

    SFLDataFormat *monoBuffer = new SFLDataFormat[decodedSize];
    SFLDataFormat *bufpos = monoBuffer;
    unsigned char *filepos = reinterpret_cast<unsigned char *>(&fileBuffer[0]);
    size_ = decodedSize;

    while (length >= encFrameSize) {
        bufpos += audioCodec_->decode(bufpos, filepos, encFrameSize);
        filepos += encFrameSize;
        length -= encFrameSize;
    }

    if (sampleRate == audioRate)
        buffer_ = monoBuffer;
    else {
        double factord = (double) sampleRate / audioRate;
        float* floatBufferIn = new float[size_];
        int    sizeOut  = ceil(factord * size_);
        src_short_to_float_array(monoBuffer, floatBufferIn, size_);
        delete [] monoBuffer;
        delete [] buffer_;
        buffer_ = new SFLDataFormat[sizeOut];

        SRC_DATA src_data;
        src_data.data_in = floatBufferIn;
        src_data.input_frames = size_;
        src_data.output_frames = sizeOut;
        src_data.src_ratio = factord;

        float* floatBufferOut = new float[sizeOut];
        src_data.data_out = floatBufferOut;

        src_simple(&src_data, SRC_SINC_BEST_QUALITY, 1);
        src_float_to_short_array(floatBufferOut, buffer_, src_data.output_frames_gen);

        delete [] floatBufferOut;
        delete [] floatBufferIn;
        size_ = src_data.output_frames_gen;
    }
}
コード例 #21
0
ファイル: shmsrc~.c プロジェクト: vliaskov/shmdata
static void 
shmsrc_tilde_try_pop_audio_buf (t_shmsrc_tilde *x)
{
  //g_print ("length %d\n", g_async_queue_length (x->x_audio_queue));
  x->x_current_audio_buf = g_async_queue_try_pop (x->x_audio_queue);

  if (x->x_current_audio_buf == NULL)
      return;
  
  double src_ratio;
  if (x->x_sample_duration < 1.0  || x->x_stream_sample_duration < 1.0)
    src_ratio = (double) x->x_pd_samplerate  
      / (double)x->x_current_audio_buf->sample_rate; 
  else 
    src_ratio =  x->x_stream_sample_duration / x->x_sample_duration; 

  /* g_print ("x->x_pd_samplerate %d x->x_current_audio_buf->sample_rate %d\n", x->x_pd_samplerate, x->x_current_audio_buf->sample_rate);  */
  /* g_print ("x->x_sample_duration %f x->x_stream_sample_duration %f\n", x->x_sample_duration, x->x_stream_sample_duration);  */
  /* g_print ("%f queue length %d, stream sample dur %f, sample duration %f\n",      */
  /* 	   src_ratio,       */
  /* 	   g_async_queue_length (x->x_audio_queue),      */
  /* 	   x->x_stream_sample_duration,      */
  /* 	   x->x_sample_duration);      */
  
  if (src_ratio == 1 )
    return;
  
  SRC_DATA src_data ;  
  int error, terminate ;  
  int input_len = x->x_current_audio_buf->remaining_samples;  
  
  int output_len = floor (input_len * src_ratio);  
  
  if (output_len == 0)
    return;
  
  //g_print ("%d, %d\n",output_len,input_len);
  src_data.data_in = x->x_current_audio_buf->audio_data ;  
  src_data.input_frames = input_len ;  
  
  src_data.src_ratio =  src_ratio;  
  
  
  //g_print ("outputlen %d channels %d\n", output_len, x->x_current_audio_buf->num_channels_in_buf);
  t_float *output = g_malloc0 (sizeof (t_float) 
			       * output_len 
			       * x->x_current_audio_buf->num_channels_in_buf);  
  src_data.data_out = output ;  
  src_data.output_frames = output_len;  
  
  //SRC_ZERO_ORDER_HOLD SRC_LINEAR SRC_SINC_FASTEST    
  if ((error = src_simple (&src_data, SRC_SINC_FASTEST, x->x_current_audio_buf->num_channels_in_buf))) 
    printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;    
  
  terminate = (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;   
	      
  if (fabs (src_data.output_frames_gen - src_ratio * input_len) > 2 * terminate)   
    {	   
      printf ("\n\nLine %d : bad output data length %ld should be %d.\n", __LINE__,   
	      src_data.output_frames_gen, (int) floor (src_ratio * input_len)) ;   
      printf ("\tsrc_ratio  : %.4f\n", src_ratio) ;   
      printf ("\tinput_len  : %d\n\toutput_len : %d\n\n", input_len, output_len) ;   
    }

  if (x->x_current_audio_buf->free_audio_data)   
    g_free (x->x_current_audio_buf->audio_data);
  x->x_current_audio_buf->free_audio_data = TRUE;   
  x->x_current_audio_buf->audio_data = output;   
  x->x_current_audio_buf->remaining_samples = output_len; 
} 
コード例 #22
0
ファイル: sdlaudio.cpp プロジェクト: JonnyH/ktftd
static void* convertAudio(void* srcBuffer, int srcSampleCount, int srcFreq, int srcBits, bool srcIsSigned,
                             int &dstSampleCount, int dstFreq, int dstBits, bool dstIsSigned)
{
	std::unique_ptr<float[]> srcFloatBuffer, dstFloatBuffer;
	srcFloatBuffer = std::unique_ptr<float[]>(new float[srcSampleCount]);
	void* outputBuffer = nullptr;

	switch (srcBits)
	{
		case 8:
		{
			if (srcIsSigned)
			{
				int8_t *i8SrcBuffer = static_cast<int8_t*>(srcBuffer);
				for (int i = 0; i < srcSampleCount; i++)
				{
					srcFloatBuffer[i] = (float)i8SrcBuffer[i] / 127.0f;
				}
			}
			else
			{
				assert(0);
			}
			break;
		}
		default:
			assert(0);
	}

	double resampleRatio = (double)dstFreq/(double)srcFreq;

	dstSampleCount = srcSampleCount*resampleRatio;

	dstFloatBuffer = std::unique_ptr<float[]>(new float[dstSampleCount]);

	SRC_DATA resampleSrc;
	resampleSrc.data_in = srcFloatBuffer.get();
	resampleSrc.data_out = dstFloatBuffer.get();
	resampleSrc.input_frames = srcSampleCount;
	resampleSrc.output_frames = dstSampleCount;
	resampleSrc.src_ratio = resampleRatio;

	int ret = src_simple(&resampleSrc, SRC_SINC_BEST_QUALITY, 1);

	if (ret != 0)
	{
		std::cerr << "Failed to resample data, error: " << src_strerror(ret) << std::endl;
		return nullptr;
	}

	assert(resampleSrc.output_frames_gen == dstSampleCount);
	assert(resampleSrc.input_frames_used == srcSampleCount);

	switch (dstBits)
	{
		case 16:
		{
			if (dstIsSigned)
			{
				int16_t* dstBuffer = new int16_t[dstSampleCount];
				for (int i = 0; i < dstSampleCount; i++)
				{
					dstBuffer[i] = dstFloatBuffer[i]*(1<<15);
				}
				outputBuffer = dstBuffer;
			}
			else
			{
				assert(0);
			}
			break;
		}
		default:
			assert(0);
	}

	return outputBuffer;
}
コード例 #23
0
ファイル: wave.c プロジェクト: EQ4/phasex
int
load_waveform_sample(int wavenum, int num_cycles, double octaves)
{
	float           *in_buf;
	float           *out_buf;
	char            filename[PATH_MAX];
	struct stat     statbuf;
	SRC_DATA        src_data;
	FILE            *rawfile;
	unsigned int    sample;
	unsigned int    input_len;
	float           pos_max;
	float           neg_max;
	float           offset;
	float           scalar;
	size_t          sample_t_size = sizeof(sample_t);

	if ((in_buf = malloc(2 * WAVEFORM_SIZE * sizeof(float))) == NULL) {
		phasex_shutdown("Out of Memory!\n");
	}
	if ((out_buf = malloc(WAVEFORM_SIZE * sizeof(float))) == NULL) {
		phasex_shutdown("Out of Memory!\n");
	}

	/* get file size */
	snprintf(filename, PATH_MAX, "%s/%s.raw", SAMPLE_DIR, wave_names[wavenum]);
	if (stat(filename, &statbuf) != 0) {
		PHASEX_ERROR("Unable to load raw sample file '%s'\n", filename);
	}
	input_len = (unsigned int)((unsigned int) statbuf.st_size / sizeof(float));
	PHASEX_DEBUG(DEBUG_CLASS_INIT, "Loading raw waveform '%s': %d samples\n",
	             filename, input_len);

	/* open raw sample file */
	if ((rawfile = fopen(filename, "rb")) != 0) {

		/* read sample data */
		if (fread(in_buf, sizeof(float), input_len, rawfile) == input_len) {
			fclose(rawfile);

			/* normalize sample to [-1,1] */
			pos_max = neg_max = 0;
			for (sample = 0; sample < input_len; sample++) {
				if (in_buf[sample] > pos_max) {
					pos_max = in_buf[sample];
				}
				if (in_buf[sample] < neg_max) {
					neg_max = in_buf[sample];
				}
			}
			offset = (pos_max + neg_max) / -2.0;
			scalar = 1.0 / (float)((pos_max - neg_max) / 2.0);
			for (sample = 0; sample < input_len; sample++) {
				in_buf[sample] = (in_buf[sample] + offset) * scalar;
			}

			/* resample to fit WAVEFORM_SIZE */
			src_data.input_frames  = (long int) input_len;
			src_data.output_frames = WAVEFORM_SIZE;
			src_data.src_ratio     = F_WAVEFORM_SIZE / (double) input_len;
			src_data.data_in       = in_buf;
			src_data.data_out      =
				(sample_t_size == 4) ? (float *) & (wave_table[wavenum][0]) : & (out_buf[0]);

			src_simple(&src_data, SRC_SINC_BEST_QUALITY, 1);

			if (sample_t_size != 4) {
				for (sample = 0; sample < input_len; sample++) {
					wave_table[wavenum][sample] = (sample_t)(out_buf[sample]);
				}
			}

			/* filter resampled data */
			filter_wave_table_24dB(wavenum, num_cycles, octaves);

			/* all done */
			return 0;
		}
		fclose(rawfile);
	}

	/* copy sine data on failure */
	PHASEX_ERROR("Error reading '%s'!\n", filename);
	for (sample = 0; sample < WAVEFORM_SIZE; sample++) {
		wave_table[wavenum][sample] = wave_table[WAVE_SINE][sample];
	}

	return -1;
}
コード例 #24
0
void
SamplePlayer::loadSampleData(QString path)
{
    SF_INFO info;
    SNDFILE *file;
    size_t samples = 0;
    float *tmpFrames, *tmpSamples, *tmpResamples, *tmpOld;
    size_t i;

    info.format = 0;
    file = sf_open(path.toLocal8Bit().data(), SFM_READ, &info);
    if (!file) {
	std::cerr << "SamplePlayer::loadSampleData: Failed to open file "
		  << path.toLocal8Bit().data() << ": "
		  << sf_strerror(file) << std::endl;
	return;
    }
    
    samples = info.frames;
    tmpFrames = (float *)malloc(info.frames * info.channels * sizeof(float));
    if (!tmpFrames) return;

    sf_readf_float(file, tmpFrames, info.frames);
    sf_close(file);

    tmpResamples = 0;

    if (info.samplerate != m_sampleRate) {
	
	double ratio = (double)m_sampleRate / (double)info.samplerate;
	size_t target = (size_t)(info.frames * ratio);
	SRC_DATA data;

	tmpResamples = (float *)malloc(target * info.channels * sizeof(float));
	if (!tmpResamples) {
	    free(tmpFrames);
	    return;
	}

	memset(tmpResamples, 0, target * info.channels * sizeof(float));

	data.data_in = tmpFrames;
	data.data_out = tmpResamples;
	data.input_frames = info.frames;
	data.output_frames = target;
	data.src_ratio = ratio;

	if (!src_simple(&data, SRC_SINC_BEST_QUALITY, info.channels)) {
	    free(tmpFrames);
	    tmpFrames = tmpResamples;
	    samples = target;
	} else {
	    free(tmpResamples);
	}
    }

    /* add an extra sample for linear interpolation */
    tmpSamples = (float *)malloc((samples + 1) * sizeof(float));
    if (!tmpSamples) {
	free(tmpFrames);
	return;
    }

    for (i = 0; i < samples; ++i) {
	int j;
	tmpSamples[i] = 0.0f;
	for (j = 0; j < info.channels; ++j) {
	    tmpSamples[i] += tmpFrames[i * info.channels + j];
	}
    }

    free(tmpFrames);

    /* add an extra sample for linear interpolation */
    tmpSamples[samples] = 0.0f;
    
    QMutexLocker locker(&m_mutex);

    tmpOld = m_sampleData;
    m_sampleData = tmpSamples;
    m_sampleCount = samples;

    for (i = 0; i < Polyphony; ++i) {
	m_ons[i] = -1;
	m_offs[i] = -1;
	m_velocities[i] = 0;
    }

    if (tmpOld) free(tmpOld);

    printf("%s: loaded %s (%ld samples from original %ld channels resampled from %ld frames at %ld Hz)\n", "sampler", path.toLocal8Bit().data(), (long)samples, (long)info.channels, (long)info.frames, (long)info.samplerate);
}
コード例 #25
0
char *samplerLoad(Sampler *plugin_data, const char *path)
{
    SF_INFO info;
    SNDFILE *file;
    size_t samples = 0;
    float *tmpFrames, *tmpSamples[2], *tmpResamples, *tmpOld[2];
    char *revisedPath = 0;
    size_t i;

    info.format = 0;
    file = sf_open(path, SFM_READ, &info);

    if (!file) {

	const char *filename = strrchr(path, '/');
	if (filename) ++filename;
	else filename = path;

	if (*filename && plugin_data->projectDir) {
	    revisedPath = (char *)malloc(strlen(filename) +
					 strlen(plugin_data->projectDir) + 2);
	    sprintf(revisedPath, "%s/%s", plugin_data->projectDir, filename);
	    file = sf_open(revisedPath, SFM_READ, &info);
	    if (!file) {
		free(revisedPath);
	    }
	}

	if (!file) {
	    return dssi_configure_message
		("error: unable to load sample file '%s'", path);
	}
    }
    
    if (info.frames > Sampler_FRAMES_MAX) {
	return dssi_configure_message
	    ("error: sample file '%s' is too large (%ld frames, maximum is %ld)",
	     path, info.frames, Sampler_FRAMES_MAX);
    }

    //!!! complain also if more than 2 channels

    samples = info.frames;

    tmpFrames = (float *)malloc(info.frames * info.channels * sizeof(float));
    sf_readf_float(file, tmpFrames, info.frames);
    sf_close(file);

    tmpResamples = 0;

    if (info.samplerate != plugin_data->sampleRate) {
	
	double ratio = (double)plugin_data->sampleRate / (double)info.samplerate;
	size_t target = (size_t)(info.frames * ratio);
	SRC_DATA data;

	tmpResamples = (float *)malloc(target * info.channels * sizeof(float));
	memset(tmpResamples, 0, target * info.channels * sizeof(float));

	data.data_in = tmpFrames;
	data.data_out = tmpResamples;
	data.input_frames = info.frames;
	data.output_frames = target;
	data.src_ratio = ratio;

	if (!src_simple(&data, SRC_SINC_BEST_QUALITY, info.channels)) {
	    free(tmpFrames);
	    tmpFrames = tmpResamples;
	    samples = target;
	} else {
	    free(tmpResamples);
	}
    }

    /* add an extra sample for linear interpolation */
    tmpSamples[0] = (float *)malloc((samples + 1) * sizeof(float));

    if (plugin_data->channels == 2) {
	tmpSamples[1] = (float *)malloc((samples + 1) * sizeof(float));
    } else {
	tmpSamples[1] = NULL;
    }


    if (plugin_data->channels == 2) {
	for (i = 0; i < samples; ++i) {
	    int j;
	    for (j = 0; j < 2; ++j) {
		if (j == 1 && info.frames < 2) {
		    tmpSamples[j][i] = tmpSamples[0][i];
		} else {
		    tmpSamples[j][i] = tmpFrames[i * info.channels + j];
		}
	    }
	}
    } else {
	for (i = 0; i < samples; ++i) {
	    int j;
	    tmpSamples[0][i] = 0.0f;
	    for (j = 0; j < info.channels; ++j) {
		tmpSamples[0][i] += tmpFrames[i * info.channels + j];
	    }
	}
    }

    free(tmpFrames);

    /* add an extra sample for linear interpolation */
    tmpSamples[0][samples] = 0.0f;
    if (plugin_data->channels == 2) {
	tmpSamples[1][samples] = 0.0f;
    }
    
    pthread_mutex_lock(&plugin_data->mutex);

    tmpOld[0] = plugin_data->sampleData[0];
    tmpOld[1] = plugin_data->sampleData[1];
    plugin_data->sampleData[0] = tmpSamples[0];
    plugin_data->sampleData[1] = tmpSamples[1];
    plugin_data->sampleCount = samples;

    for (i = 0; i < Sampler_NOTES; ++i) {
	plugin_data->ons[i] = -1;
	plugin_data->offs[i] = -1;
	plugin_data->velocities[i] = 0;
    }

    pthread_mutex_unlock(&plugin_data->mutex);

    if (tmpOld[0]) free(tmpOld[0]);
    if (tmpOld[1]) free(tmpOld[1]);

    printf("%s: loaded %s (%ld samples from original %ld channels resampled from %ld frames at %ld Hz)\n", (plugin_data->channels == 2 ? Sampler_Stereo_LABEL : Sampler_Mono_LABEL), path, (long)samples, (long)info.channels, (long)info.frames, (long)info.samplerate);

    if (revisedPath) {
	char *message = dssi_configure_message("warning: sample file '%s' not found: loading from '%s' instead", path, revisedPath);
	free(revisedPath);
	return message;
    }

    return NULL;
}