Beispiel #1
0
static void
Close( vlc_object_t *p_obj )
{
    filter_t *p_filter = (filter_t *)p_obj;
    filter_sys_t *p_sys = p_filter->p_sys;

    soxr_delete( p_sys->soxr );
    if( p_sys->vr_soxr )
        soxr_delete( p_sys->vr_soxr );

    free( p_sys );
}
Beispiel #2
0
static struct ResampleContext *create(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
        double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta, double precision, int cheby){
    soxr_error_t error;

    soxr_datatype_t type =
        format == AV_SAMPLE_FMT_S16P? SOXR_INT16_S :
        format == AV_SAMPLE_FMT_S16 ? SOXR_INT16_I :
        format == AV_SAMPLE_FMT_S32P? SOXR_INT32_S :
        format == AV_SAMPLE_FMT_S32 ? SOXR_INT32_I :
        format == AV_SAMPLE_FMT_FLTP? SOXR_FLOAT32_S :
        format == AV_SAMPLE_FMT_FLT ? SOXR_FLOAT32_I :
        format == AV_SAMPLE_FMT_DBLP? SOXR_FLOAT64_S :
        format == AV_SAMPLE_FMT_DBL ? SOXR_FLOAT64_I : (soxr_datatype_t)-1;

    soxr_io_spec_t io_spec = soxr_io_spec(type, type);

    soxr_quality_spec_t q_spec = soxr_quality_spec((int)((precision-2)/4), (SOXR_HI_PREC_CLOCK|SOXR_ROLLOFF_NONE)*!!cheby);
    q_spec.precision = linear? 0 : precision;
#if !defined SOXR_VERSION /* Deprecated @ March 2013: */
    q_spec.bw_pc = cutoff? FFMAX(FFMIN(cutoff,.995),.8)*100 : q_spec.bw_pc;
#else
    q_spec.passband_end = cutoff? FFMAX(FFMIN(cutoff,.995),.8) : q_spec.passband_end;
#endif

    soxr_delete((soxr_t)c);
    c = (struct ResampleContext *)
        soxr_create(in_rate, out_rate, 0, &error, &io_spec, &q_spec, 0);
    if (!c)
        av_log(NULL, AV_LOG_ERROR, "soxr_create: %s\n", error);
    return c;
}
Beispiel #3
0
int resample_close(struct resample_handle *h)
{
	if(h == NULL)
		return 0;

	/* Close libsoxr */
	if(h->soxr != NULL)
		soxr_delete(h->soxr);

	/* Free specs for down/up-mixing */
	if(h->out_specs != NULL)
	{
		int i;
		for(i = 0; i < h->out_nb_channel; i++)
			if(h->out_specs[i].in_specs != NULL)
				free(h->out_specs[i].in_specs);
		free(h->out_specs);
	}

	/* Free buffer */
	if(h->buffer != NULL)
		free(h->buffer);
	if(h->buffer_out != NULL)
		free(h->buffer_out);

	/* Free structure */
	free(h);

	return 0;
}
Beispiel #4
0
void DSD2PCM::Open(long DSDsamplesPerSec, int desiredSampleRate, int ch, int desiredWordSize)
{
	dsd_samples_per_sec = DSDsamplesPerSec;
	channels = ch;
	wordSize = desiredWordSize;
	desired_sample_rate = desiredSampleRate;

	ds.clear();
	ns.clear();
	buffer.clear();
	buffer_stored = 0;
	flush_phase = false;

	for (int i = 0; i < ch; ++i) {
		ds.push_back(Downsampler(ds_pc));
		ns.push_back(Noiseshaper());
	}
	if (soxr != NULL) {
		soxr_delete(soxr);
	}
	{
		soxr_error_t e = NULL;
		soxr_runtime_spec_t spec = soxr_runtime_spec(0);
		soxr = soxr_create(DSDsamplesPerSec / 8, desiredSampleRate, ch, &e, NULL, NULL, &spec);
		if (e != NULL) {
			OutputDebugStringA((char*)e);
			DebugBreak();
		}

	}
}
Beispiel #5
0
void DSD2PCM::Close()
{
	dsd_samples_per_sec = channels = 0;
	ds.clear();
	ns.clear();
	buffer.clear();
	buffer_stored = 0;

	if (soxr != NULL) {
		soxr_delete(soxr);
		soxr = NULL;
	}
}
Beispiel #6
0
void BE_ST_ShutdownAudio(void)
{
	if (g_sdlAudioSubsystemUp)
	{
		if ((g_sdlAudioSpec.callback == BEL_ST_Resampling_EmuCallBack) || (g_sdlAudioSpec.callback == BEL_ST_Resampling_DigiCallBack))
		{
#ifndef REFKEEN_RESAMPLER_NONE
			if (g_refKeenCfg.useResampler)
			{
#if (defined REFKEEN_RESAMPLER_LIBSWRESAMPLE)
				swr_free(&g_sdlSwrContext);
#elif (defined REFKEEN_RESAMPLER_LIBAVRESAMPLE)
				avresample_free(&g_sdlAvAudioResampleContext);
#elif (defined REFKEEN_RESAMPLER_LIBAVCODEC)
				av_resample_close(g_sdlAvResampleContext);
#elif (defined REFKEEN_RESAMPLER_LIBRESAMPLE)
				resample_close(g_sdlResampleHandle);
#elif (defined REFKEEN_RESAMPLER_LIBSOXR)
				soxr_delete(g_sdlSoxr);
#elif (defined REFKEEN_RESAMPLER_LIBSPEEXDSP)
				speex_resampler_destroy(g_sdlSpeexResamplerState);
#elif (defined REFKEEN_RESAMPLER_LIBSAMPLERATE)
				src_delete(g_sdlSrcResampler);
#endif
			}
			else
#endif // REFKEEN_RESAMPLER_NONE
			{
				free(g_sdlSampleRateConvTable);
			}
		}
#ifdef REFKEEN_CONFIG_THREADS
		SDL_DestroyMutex(g_sdlCallbackMutex);
		g_sdlCallbackMutex = NULL;
#endif
		SDL_CloseAudio();
		SDL_QuitSubSystem(SDL_INIT_AUDIO);
		g_sdlAudioSubsystemUp = false;
	}
	g_sdlCallbackSDFuncPtr = 0; // Just in case this may be called after the audio subsystem was never really started (manual calls to callback)
}
Beispiel #7
0
 VarRateResample::~VarRateResample()
 {
    soxr_delete((soxr_t)mHandle);
    mHandle = NULL;
 }
Beispiel #8
0
static void destroy(struct ResampleContext * *c){
    soxr_delete((soxr_t)*c);
    *c = NULL;
}
Beispiel #9
0
static int
Open( vlc_object_t *p_obj, bool b_change_ratio )
{
    filter_t *p_filter = (filter_t *)p_obj;

    /* Cannot remix */
    if( p_filter->fmt_in.audio.i_channels != p_filter->fmt_out.audio.i_channels )
        return VLC_EGENERIC;

    /* Get SoXR input/output format */
    soxr_datatype_t i_itype, i_otype;
    if( !SoXR_GetFormat( p_filter->fmt_in.audio.i_format, &i_itype )
     || !SoXR_GetFormat( p_filter->fmt_out.audio.i_format, &i_otype ) )
        return VLC_EGENERIC;

    filter_sys_t *p_sys = calloc( 1, sizeof( filter_sys_t ) );
    if( unlikely( p_sys == NULL ) )
        return VLC_ENOMEM;

    /* Setup SoXR */
    int64_t i_vlc_q = var_InheritInteger( p_obj, "soxr-resampler-quality" );
    if( i_vlc_q < 0 )
        i_vlc_q = 0;
    else if( i_vlc_q > MAX_SOXR_QUALITY )
        i_vlc_q = MAX_SOXR_QUALITY;
    const unsigned long i_recipe = soxr_resampler_quality_list[i_vlc_q];
    const unsigned i_channels = p_filter->fmt_in.audio.i_channels;
    const double f_ratio = p_filter->fmt_out.audio.i_rate
                           / (double) p_filter->fmt_in.audio.i_rate;

    p_sys->f_fixed_ratio = f_ratio;
    soxr_error_t error;
    /* IO spec */
    soxr_io_spec_t io_spec = soxr_io_spec( i_itype, i_otype );
    /* Quality spec */
    soxr_quality_spec_t q_spec = soxr_quality_spec( i_recipe, 0 );
    /* Create SoXR */
    p_sys->soxr = soxr_create( 1, f_ratio, i_channels,
                               &error, &io_spec, &q_spec, NULL );
    if( error )
    {
        msg_Err( p_filter, "soxr_create failed: %s", soxr_strerror( error ) );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Create a 'variable-rate' SoXR if needed: it is slower than the fixed
     * one, but it will be only used when the input rate is changing (to catch
     * up a delay).  */
    if( b_change_ratio )
    {
        q_spec = soxr_quality_spec( SOXR_LQ, SOXR_VR );
        p_sys->vr_soxr = soxr_create( 1, f_ratio, i_channels,
                                      &error, &io_spec, &q_spec, NULL );
        if( error )
        {
            msg_Err( p_filter, "soxr_create failed: %s", soxr_strerror( error ) );
            soxr_delete( p_sys->soxr );
            free( p_sys );
            return VLC_EGENERIC;
        }
        soxr_set_io_ratio( p_sys->vr_soxr, 1 / f_ratio, 0 );
    }

    msg_Dbg( p_filter, "Using SoX Resampler with '%s' engine and '%s' quality "
             "to convert %4.4s/%dHz to %4.4s/%dHz.",
             soxr_engine( p_sys->soxr ), soxr_resampler_quality_vlctext[i_vlc_q],
             (const char *)&p_filter->fmt_in.audio.i_format,
             p_filter->fmt_in.audio.i_rate,
             (const char *)&p_filter->fmt_out.audio.i_format,
             p_filter->fmt_out.audio.i_rate );

    p_filter->p_sys = p_sys;
    p_filter->pf_audio_filter = Resample;
    p_filter->pf_flush = Flush;
    p_filter->pf_audio_drain = Drain;
    return VLC_SUCCESS;
}
Beispiel #10
0
void Resampler::Resample(unsigned int in_channels, unsigned int in_sample_rate, AVSampleFormat in_format, unsigned int in_sample_count, const uint8_t* in_data,
						 unsigned int out_channels, unsigned int out_sample_rate, AVSampleFormat out_format, unsigned int* out_sample_count, const uint8_t** out_data) {
	Q_ASSERT(in_channels > 0 && out_channels > 0);
	Q_ASSERT(in_sample_rate > 0 && out_sample_rate > 0);
	Q_ASSERT(in_channels == out_channels);
	Q_ASSERT(out_format == AV_SAMPLE_FMT_FLT);

	if(m_started) {
		Q_ASSERT(m_out_channels == out_channels);
		Q_ASSERT(m_out_sample_rate == out_sample_rate);
	} else {
		m_started = true;
		m_in_sample_rate = 0; // trigger creation of new resampler
		m_out_channels = out_channels;
		m_out_sample_rate = out_sample_rate;
	}

	// prepare output samples
	unsigned int out_pos = 0;
	m_out_data.alloc(16 * 1024);

	// do we need a new resampler?
	if(in_sample_rate != m_in_sample_rate) {

		// delete old resampler
		if(m_soxr != NULL) {

			// flush resampler
			for( ; ; ) {
				size_t out_done;
				soxr_error_t error = soxr_process(m_soxr,
												  NULL, 0, NULL,
												  m_out_data.data() + out_pos * out_channels * sizeof(float), m_out_data.size() / (out_channels * sizeof(float)) - out_pos, &out_done);
				if(error != NULL) {
					Logger::LogError("[Resampler::Resample] " + QObject::tr("Error: Flushing resampler failed! Reason: %s").arg(soxr_strerror(error)));
					throw SoxrException();
				}
				out_pos += out_done;
				if(out_pos < m_out_data.size() / (out_channels * sizeof(float)))
					break;
				m_out_data.realloc(m_out_data.size() * 2);
			}

			soxr_delete(m_soxr);
			m_soxr = NULL;
		}

		m_in_sample_rate = in_sample_rate;

		// do we really need a resampler?
		if(m_in_sample_rate != m_out_sample_rate) {
			Logger::LogInfo("[Resampler::Resampler] " + QObject::tr("Resampling from %1 to %2.").arg(m_in_sample_rate).arg(m_out_sample_rate));
			soxr_error_t error;
			soxr_quality_spec_t quality = soxr_quality_spec(SOXR_MQ, 0);
			m_soxr = soxr_create((double) m_in_sample_rate, (double) m_out_sample_rate, out_channels, &error, NULL, &quality, NULL);
			if(m_soxr == NULL || error != NULL) {
				m_in_sample_rate = 0;
				Logger::LogError("[Resampler::Resampler] " + QObject::tr("Error: Can't create resampler! Reason: %s").arg(soxr_strerror(error)));
				throw SoxrException();
			}
		} else {
			Logger::LogInfo("[Resampler::Resampler] " + QObject::tr("Resampling not needed."));
		}

	}

	// prepare input samples
	uint8_t *in_data_float;
	unsigned int in_pos = 0;
	if(in_format == AV_SAMPLE_FMT_FLT) {
		in_data_float = (uint8_t*) in_data;
	} else if(in_format == AV_SAMPLE_FMT_S16) {
		m_in_data.alloc(in_sample_count * out_channels * sizeof(float));
		SampleCopy(in_sample_count * out_channels, (const int16_t*) in_data, 1, (float*) m_in_data.data(), 1);
		in_data_float = (uint8_t*) m_in_data.data();
	} else {
		Q_ASSERT(false); // unsupported input format
		return;
	}

	// no resampling needed?
	if(m_in_sample_rate == m_out_sample_rate) {
		if(out_pos == 0) {
			*out_sample_count = in_sample_count;
			*out_data = in_data_float;
		} else {
			m_out_data.realloc((out_pos + in_sample_count) * out_channels * sizeof(float));
			memcpy(m_out_data.data() + out_pos * out_channels * sizeof(float), in_data_float, in_sample_count * out_channels * sizeof(float));
			*out_sample_count = out_pos + in_sample_count;
			*out_data = m_out_data.data();
		}
		return;
	}

	// resample
	for( ; ; ) {
		size_t in_done, out_done;
		soxr_error_t error = soxr_process(m_soxr,
										  in_data_float + in_pos * out_channels * sizeof(float), in_sample_count - in_pos, &in_done,
										  m_out_data.data() + out_pos * out_channels * sizeof(float), m_out_data.size() / (out_channels * sizeof(float)) - out_pos, &out_done);
		if(error != NULL) {
			Logger::LogError("[Resampler::Resample] " + QObject::tr("Error: Resampling failed!"));
			throw SoxrException();
		}
		in_pos += in_done;
		out_pos += out_done;
		if(in_pos == in_sample_count)
			break;
		m_out_data.realloc(m_out_data.size() * 2);
	}

	*out_sample_count = out_pos;
	*out_data = m_out_data.data();

}
Beispiel #11
0
Resampler::~Resampler() {
	if(m_soxr != NULL) {
		soxr_delete(m_soxr);
		m_soxr = NULL;
	}
}
Beispiel #12
0
int main(int n, char const * arg[])
{
  char const *     const arg0 = n? --n, *arg++ : "", * engine = "";
  double          const irate = n? --n, atof(*arg++) : 96000.;
  double          const orate = n? --n, atof(*arg++) : 44100.;
  unsigned        const chans = n? --n, (unsigned)atoi(*arg++) : 1;
  soxr_datatype_t const itype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
  unsigned        const ospec = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
  unsigned long const q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
  unsigned long const q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
  double   const passband_end = n? --n, atof(*arg++) : 0;
  double const stopband_begin = n? --n, atof(*arg++) : 0;
  double const phase_response = n? --n, atof(*arg++) : -1;
  int       const use_threads = n? --n, atoi(*arg++) : 1;
  soxr_datatype_t const otype = ospec & 3;

  soxr_quality_spec_t       q_spec = soxr_quality_spec(q_recipe, q_flags);
  soxr_io_spec_t            io_spec = soxr_io_spec(itype, otype);
  soxr_runtime_spec_t const runtime_spec = soxr_runtime_spec(!use_threads);

  /* Allocate resampling input and output buffers in proportion to the input
   * and output rates: */
  #define buf_total_len 15000  /* In samples per channel. */
  size_t const osize = soxr_datatype_size(otype) * chans;
  size_t const isize = soxr_datatype_size(itype) * chans;
  size_t const olen0= (size_t)(orate * buf_total_len / (irate + orate) + .5);
  size_t const olen = min(max(olen0, 1), buf_total_len - 1);
  size_t const ilen = buf_total_len - olen;
  void * const obuf = malloc(osize * olen);
  void * const ibuf = malloc(isize * ilen);

  size_t odone = 0, clips = 0, omax = 0, i;
  soxr_error_t error;
  soxr_t soxr;
  int32_t seed = 0;
  char const * e = getenv("SOXR_THROUGHPUT_GAIN");
  double gain = e? atof(e) : .5;

  /* Overrides (if given): */
  if (passband_end   > 0) q_spec.passband_end   = passband_end / 100;
  if (stopband_begin > 0) q_spec.stopband_begin = stopband_begin / 100;
  if (phase_response >=0) q_spec.phase_response = phase_response;
  io_spec.flags = ospec & ~7u;

  /* Create a stream resampler: */
  soxr = soxr_create(
      irate, orate, chans,         /* Input rate, output rate, # of channels. */
      &error,                         /* To report any error during creation. */
      &io_spec, &q_spec, &runtime_spec);

#define ranqd1(x) ((x) = 1664525 * (x) + 1013904223) /* int32_t x */
#define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
#define RAND (dranqd1(seed) * gain)
#define DURATION_MSECS 125
#define NUM_ATTEMPTS 8

  if (!error) {                         /* If all is well, run the resampler: */
    engine = soxr_engine(soxr);
    switch (itype & 3) {
      case 0: for (i=0;i<ilen*chans; ((float   *)ibuf)[i]=(float  )RAND, ++i); break;
      case 1: for (i=0;i<ilen*chans; ((double  *)ibuf)[i]=(double )RAND, ++i); break;
      case 2: for (i=0;i<ilen*chans; ((int32_t *)ibuf)[i]=rint32(65536.*32768*RAND), ++i); break;
      case 3: for (i=0;i<ilen*chans; ((int16_t *)ibuf)[i]=rint16(    1.*32768*RAND), ++i); break;
    }
                                                       /* Resample in blocks: */
    for (i=0; i<NUM_ATTEMPTS; ++i) {
      size_t itotal = 0, ototal = 0;
      timerStart(DURATION_MSECS);
      do {
        size_t const ilen1 = odone < olen? ilen : 0;
        error = soxr_process(soxr, ibuf, ilen1, NULL, obuf, olen, &odone);
        itotal += ilen1;
        ototal += odone;
      } while (!error && timerRunning());
      omax = max(omax, ototal);
    }
  }
                                                                  /* Tidy up: */
  clips = *soxr_num_clips(soxr);     /* Can occur only with integer output. */
  soxr_delete(soxr);
  free(obuf), free(ibuf);
                                                              /* Diagnostics: */
  fprintf(stderr, "%-26s %s; %lu clips; I/O: %s (%-5s) %.2f Ms/s\n",
      arg0, soxr_strerror(error), (long unsigned)clips,
      ferror(stdin) || ferror(stdout)? strerror(errno) : "no error", engine,
      1e-6 * k / DURATION_MSECS * chans * (double)omax);
  return !!error;
}