Exemplo n.º 1
0
std::pair<size_t, size_t>
      Resample::Process(double  factor,
                        float  *inBuffer,
                        size_t  inBufferLen,
                        bool    lastFlag,
                        float  *outBuffer,
                        size_t  outBufferLen)
{
   size_t idone, odone;
   if (mbWantConstRateResampling)
   {
      soxr_process(mHandle.get(),
            inBuffer , (lastFlag? ~inBufferLen : inBufferLen), &idone,
            outBuffer,                           outBufferLen, &odone);
   }
   else
   {
      soxr_set_io_ratio(mHandle.get(), 1/factor, 0);

      inBufferLen = lastFlag? ~inBufferLen : inBufferLen;
      soxr_process(mHandle.get(),
            inBuffer , inBufferLen , &idone,
            outBuffer, outBufferLen, &odone);
   }
   return { idone, odone };
}
Exemplo n.º 2
0
int Resample::Process(double  factor,
                        float  *inBuffer,
                        int     inBufferLen,
                        bool    lastFlag,
                        int    *inBufferUsed,
                        float  *outBuffer,
                        int     outBufferLen)
{
   size_t idone, odone;
   if (mbWantConstRateResampling)
   {
      soxr_process((soxr_t)mHandle,
            inBuffer , (size_t)(lastFlag? ~inBufferLen : inBufferLen), &idone,
            outBuffer, (size_t)                          outBufferLen, &odone);
   }
   else
   {
      soxr_set_io_ratio((soxr_t)mHandle, 1/factor, 0);

      inBufferLen = lastFlag? ~inBufferLen : inBufferLen;
      soxr_process((soxr_t)mHandle,
            inBuffer , (size_t)inBufferLen , &idone,
            outBuffer, (size_t)outBufferLen, &odone);
   }
   *inBufferUsed = (int)idone;
   return (int)odone;
}
Exemplo n.º 3
0
static int flush(struct SwrContext *s){
    s->delayed_samples_fixup = soxr_delay((soxr_t)s->resample);

    soxr_process((soxr_t)s->resample, NULL, 0, NULL, NULL, 0, NULL);

    {
        float f;
        size_t idone, odone;
        soxr_process((soxr_t)s->resample, &f, 0, &idone, &f, 0, &odone);
        s->delayed_samples_fixup -= soxr_delay((soxr_t)s->resample);
    }

    return 0;
}
Exemplo n.º 4
0
// convert channels, src is interlaced as LRLRLR...
// return: # of samples rendered
size_t DSD2PCM::Render(uint8_t* src, size_t src_size, size_t block_size, int lsbf, uint8_t* dst, size_t samplesToRender)
{
	std::vector<float> float_data(src_size, 0), resample_data(src_size, 0);
	size_t idone = 0, odone = 0;

	if (flush_phase) {
		return 0; // RenderFlush(dst, samplesToRender);
	}

	for (int ch = 0; ch < channels; ++ch) {
		ds[ch].translate(src_size / channels, src + ch * block_size, (block_size > 1) ? 1 : channels, lsbf, float_data.data() + ch, channels);
	}

	soxr_process(soxr, float_data.data(), src_size / channels, &idone, resample_data.data(), src_size / channels, &odone);
	if (odone > 0) {
		buffer.insert(buffer.end(), resample_data.begin(), resample_data.begin() + odone * channels);
		buffer_stored += odone;
	}
	if (buffer_stored >= samplesToRender) {
		size_t samplesWritten = writeFinal(buffer, samplesToRender, dst);
		if (samplesWritten > 0) {
			buffer.erase(buffer.begin(), buffer.begin() + samplesToRender * channels);
			buffer_stored -= samplesWritten;

			return samplesWritten;
		}
	}
	return 0;
}
Exemplo n.º 5
0
    DspChunk DspRate::ProcessEosChunk(soxr_t soxr, DspChunk& chunk)
    {
        assert(soxr);

        DspChunk output;

        if (!chunk.IsEmpty())
            output = ProcessChunk(soxr, chunk);

        for (;;)
        {
            DspChunk tailChunk(DspFormat::Float, m_channels, m_outputRate, m_outputRate);

            size_t inputDone = 0;
            size_t outputDo = tailChunk.GetFrameCount();
            size_t outputDone = 0;
            soxr_process(soxr, nullptr, 0, &inputDone,
                               tailChunk.GetData(), outputDo, &outputDone);
            tailChunk.ShrinkTail(outputDone);

            DspChunk::MergeChunks(output, tailChunk);

            if (outputDone < outputDo)
                break;
        }

        return output;
    }
Exemplo n.º 6
0
static int process(
        struct ResampleContext * c, AudioData *dst, int dst_size,
        AudioData *src, int src_size, int *consumed){
    size_t idone, odone;
    soxr_error_t error = soxr_set_error((soxr_t)c, soxr_set_num_channels((soxr_t)c, src->ch_count));
    error = soxr_process((soxr_t)c, src->ch, (size_t)src_size,
            &idone, dst->ch, (size_t)dst_size, &odone);
    *consumed = (int)idone;
    return error? -1 : odone;
}
Exemplo n.º 7
0
 int ConstRateResample::Process(double  factor,
                                float  *inBuffer,
                                int     inBufferLen,
                                bool    lastFlag,
                                int    *inBufferUsed,
                                float  *outBuffer,
                                int     outBufferLen)
 {
    size_t idone , odone;
    soxr_process((soxr_t)mHandle,
          inBuffer , (size_t)(lastFlag? ~inBufferLen : inBufferLen), &idone,
          outBuffer, (size_t)                          outBufferLen, &odone);
    *inBufferUsed = (int)idone;
    return (int)odone;
 }
Exemplo n.º 8
0
Arquivo: soxr.c Projeto: mstorsjo/vlc
static block_t *
SoXR_Resample( filter_t *p_filter, soxr_t soxr, block_t *p_in, size_t i_olen )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    size_t i_idone, i_odone;
    const size_t i_oframesize = p_filter->fmt_out.audio.i_bytes_per_frame;
    const size_t i_ilen = p_in ? p_in->i_nb_samples : 0;

    block_t *p_out = i_ilen >= i_olen ? p_in
                   : block_Alloc( i_olen * i_oframesize );

    soxr_error_t error = soxr_process( soxr, p_in ? p_in->p_buffer : NULL,
                                       i_ilen, &i_idone, p_out->p_buffer,
                                       i_olen, &i_odone );
    if( error )
    {
        msg_Err( p_filter, "soxr_process failed: %s", soxr_strerror( error ) );
        block_Release( p_out );
        goto error;
    }
    if( unlikely( i_idone < i_ilen ) )
        msg_Err( p_filter, "lost %zd of %zd input frames",
                 i_ilen - i_idone, i_idone);

    p_out->i_buffer = i_odone * i_oframesize;
    p_out->i_nb_samples = i_odone;
    p_out->i_length = vlc_tick_from_samples(i_odone, p_filter->fmt_out.audio.i_rate);

    if( p_in )
    {
        p_sys->i_last_olen = i_olen;
        p_sys->last_soxr = soxr;
    }
    else
    {
        soxr_clear( soxr );
        p_sys->i_last_olen = 0;
        p_sys->last_soxr = NULL;
    }

error:
    if( p_in && p_out != p_in )
        block_Release( p_in );

    return p_out;
}
Exemplo n.º 9
0
size_t DSD2PCM::RenderLast()
{
	const int src_size = 4096;
	std::vector<float> resample_data(src_size, 0);

	if (flush_phase)
		return buffer_stored;

	size_t idone = 0, odone = 0;
	do {
		soxr_process(soxr, NULL, 0, &idone, resample_data.data(), src_size / channels, &odone);
		if (odone > 0) {
			buffer.insert(buffer.end(), resample_data.begin(), resample_data.begin() + odone * channels);
			buffer_stored += odone;
		}
	} while (odone > 0);

	flush_phase = true;

	return buffer_stored;
}
Exemplo n.º 10
0
    DspChunk DspRate::ProcessChunk(soxr_t soxr, DspChunk& chunk)
    {
        assert(soxr);
        assert(!chunk.IsEmpty());
        assert(chunk.GetRate() == m_inputRate);
        assert(chunk.GetChannelCount() == m_channels);

        DspChunk::ToFloat(chunk);

        size_t outputFrames = (size_t)(2 * (uint64_t)chunk.GetFrameCount() * m_outputRate / m_inputRate);
        DspChunk output(DspFormat::Float, chunk.GetChannelCount(), outputFrames, m_outputRate);

        size_t inputDone = 0;
        size_t outputDone = 0;
        soxr_process(soxr, chunk.GetData(), chunk.GetFrameCount(), &inputDone,
                           output.GetData(), output.GetFrameCount(), &outputDone);
        assert(inputDone == chunk.GetFrameCount());
        output.ShrinkTail(outputDone);

        return output;
    }
Exemplo n.º 11
0
static int flush(struct SwrContext *s){
    soxr_process((soxr_t)s->resample, NULL, 0, NULL, NULL, 0, NULL);
    return 0;
}
Exemplo n.º 12
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();

}
Exemplo n.º 13
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;
}