AVPKit
com::avpkit::core::AudioResampler Class Reference
Inheritance diagram for com::avpkit::core::AudioResampler:
Collaboration diagram for com::avpkit::core::AudioResampler:

Public Member Functions

virtual int getOutputChannels ()
 number of channels in output audio. More...
 
virtual int getOutputRate ()
 sample rate of output audio. More...
 
virtual int getInputChannels ()
 number of channels expected in input audio. More...
 
virtual int getInputRate ()
 sample rate expected in input audio. More...
 
virtual int resample (IAudioSamples *pOutputSamples, IAudioSamples *pInputSamples, int32_t numSamples)
 Re-sample up to numSamples from inputSamples to outputSamples. More...
 
virtual IAudioSamples::Format getOutputFormat ()
 Get the sample format we expect to resample to. More...
 
virtual IAudioSamples::Format getInputFormat ()
 Get the sample format we expect to resample from. More...
 
virtual int32_t getFilterLen ()
 Get the length of each filter in the resampler filter bank. More...
 
virtual int32_t getLog2PhaseCount ()
 Get log2(number of entries in filter bank). More...
 
virtual bool isLinear ()
 Are we linearly interpolating between filters? More...
 
virtual double getCutoffFrequency ()
 What is the cuttoff frequency used? More...
 
virtual int32_t getMinimumNumSamplesRequiredInOutputSamples (IAudioSamples *inSamples)
 Get the minimum number of samples that must be placeable in an output set of samples in order for a resample with this resampler to succeed. More...
 
virtual int32_t getMinimumNumSamplesRequiredInOutputSamples (int32_t numSamples)
 Get the minimum number of samples that must be placeable in an output set of samples in order for a resample with this resampler to succeed. More...
 
- Public Member Functions inherited from com::avpkit::ferry::RefCounted
virtual int32_t acquire ()
 Internal Only. More...
 
virtual int32_t release ()
 Internal Only. More...
 
virtual RefCountedcopyReference ()
 Create a new Java object that refers to the same native object. More...
 
virtual int32_t getCurrentRefCount ()
 Return the current reference count on this object. More...
 
void setJavaAllocator (void *allocator)
 This method is public but not part of the standard API. More...
 
void * getJavaAllocator ()
 This method is public but not part of the standard API. More...
 

Static Public Member Functions

static AudioResamplermake (int32_t outputChannels, int32_t inputChannels, int32_t outputRate, int32_t inputRate)
 
static AudioResamplermake (int32_t outputChannels, int32_t inputChannels, int32_t outputRate, int32_t inputRate, IAudioSamples::Format outputFmt, IAudioSamples::Format inputFmt)
 
static AudioResamplermake (int32_t outputChannels, int32_t inputChannels, int32_t outputRate, int32_t inputRate, IAudioSamples::Format outputFmt, IAudioSamples::Format inputFmt, int32_t filterLen, int32_t log2PhaseCount, bool isLinear, double cutoff)
 
- Static Public Member Functions inherited from com::avpkit::core::IAudioResampler
static IAudioResamplermake (int32_t outputChannels, int32_t inputChannels, int32_t outputRate, int32_t inputRate)
 Create a new IAudioResampler object. More...
 
static IAudioResamplermake (int32_t outputChannels, int32_t inputChannels, int32_t outputRate, int32_t inputRate, IAudioSamples::Format outputFmt, IAudioSamples::Format inputFmt)
 Create a new IAudioResampler object. More...
 
static IAudioResamplermake (int32_t outputChannels, int32_t inputChannels, int32_t outputRate, int32_t inputRate, IAudioSamples::Format outputFmt, IAudioSamples::Format inputFmt, int32_t filterLen, int32_t log2PhaseCount, bool isLinear, double cutoffFrequency)
 Create a new IAudioResampler object. More...
 

Additional Inherited Members

- Protected Member Functions inherited from com::avpkit::ferry::RefCounted
virtual void destroy ()
 This method is called by RefCounted objects when their Ref Count reaches zero and they are about to be destroyed.
 
- Protected Attributes inherited from com::avpkit::ferry::RefCounted
AtomicIntegermRefCount
 This is the internal reference count, represented as an AtomicInteger to make sure it is thread safe.
 
void * mAllocator
 Not part of public API.
 

Detailed Description

Definition at line 29 of file AudioResampler.h.

Member Function Documentation

◆ getCutoffFrequency()

double com::avpkit::core::AudioResampler::getCutoffFrequency ( )
virtual

What is the cuttoff frequency used?

Returns
the cuttoff frequency

Implements com::avpkit::core::IAudioResampler.

Definition at line 472 of file AudioResampler.cpp.

473  {
474  return mCutoff;
475  }

◆ getFilterLen()

int32_t com::avpkit::core::AudioResampler::getFilterLen ( )
virtual

Get the length of each filter in the resampler filter bank.

Returns
the filter length

Implements com::avpkit::core::IAudioResampler.

Definition at line 454 of file AudioResampler.cpp.

455  {
456  return mFilterLen;
457  }

◆ getInputChannels()

int com::avpkit::core::AudioResampler::getInputChannels ( )
virtual

number of channels expected in input audio.

Returns
Number of channels we'll expect in the input samples

Implements com::avpkit::core::IAudioResampler.

Definition at line 179 of file AudioResampler.cpp.

180  {
181  VS_ASSERT(swrContext, "no context");
182  return mIChannels;
183  }

◆ getInputFormat()

IAudioSamples::Format com::avpkit::core::AudioResampler::getInputFormat ( )
virtual

Get the sample format we expect to resample from.

Returns
the sample format for input.

Implements com::avpkit::core::IAudioResampler.

Definition at line 448 of file AudioResampler.cpp.

449  {
450  return mIFmt;
451  }

◆ getInputRate()

int com::avpkit::core::AudioResampler::getInputRate ( )
virtual

sample rate expected in input audio.

Returns
Sample rate we'll expect in the input samples

Implements com::avpkit::core::IAudioResampler.

Definition at line 186 of file AudioResampler.cpp.

187  {
188  VS_ASSERT(swrContext, "no context");
189  return mISampleRate;
190  }

◆ getLog2PhaseCount()

int32_t com::avpkit::core::AudioResampler::getLog2PhaseCount ( )
virtual

Get log2(number of entries in filter bank).

Returns
log2(number of entries in filter bank).

Implements com::avpkit::core::IAudioResampler.

Definition at line 460 of file AudioResampler.cpp.

461  {
462  return mLog2PhaseCount;
463  }

◆ getMinimumNumSamplesRequiredInOutputSamples() [1/2]

int32_t com::avpkit::core::AudioResampler::getMinimumNumSamplesRequiredInOutputSamples ( IAudioSamples inSamples)
virtual

Get the minimum number of samples that must be placeable in an output set of samples in order for a resample with this resampler to succeed.

Parameters
inSamplesThe input samples that will be passed to resample.
Returns
The minimum number of samples, or < 0 on error.
Since
3.2

Implements com::avpkit::core::IAudioResampler.

Definition at line 193 of file AudioResampler.cpp.

195  {
196  int32_t retval = -1;
197  try {
198  int32_t numSamples = 0;
199  if (inSamples)
200  {
201  if (!inSamples->isComplete())
202  throw std::invalid_argument("input samples are not complete");
203 
204  if (inSamples->getSampleRate() != mISampleRate)
205  throw std::invalid_argument("unexpected input sample rate");
206 
207  if (inSamples->getChannels() != mIChannels)
208  throw std::invalid_argument("unexpected # of input channels");
209 
210  if (inSamples->getFormat() != mIFmt)
211  throw std::invalid_argument("unexpected sample format");
212 
213  numSamples = inSamples->getNumSamples();
214  } else {
215  numSamples = 0;
216  }
217  retval = getMinimumNumSamplesRequiredInOutputSamples(numSamples);
218  }
219  catch (std::invalid_argument & e)
220  {
221  VS_LOG_DEBUG("invalid argument: %s", e.what());
222  retval = -1;
223  }
224  catch (std::exception & e)
225  {
226  VS_LOG_DEBUG("Unknown exception: %s", e.what());
227  }
228  return retval;
229  }
virtual int32_t getMinimumNumSamplesRequiredInOutputSamples(IAudioSamples *inSamples)
Get the minimum number of samples that must be placeable in an output set of samples in order for a r...

References com::avpkit::core::IAudioSamples::getChannels(), com::avpkit::core::IAudioSamples::getFormat(), com::avpkit::core::IAudioSamples::getNumSamples(), com::avpkit::core::IAudioSamples::getSampleRate(), and com::avpkit::core::IAudioSamples::isComplete().

◆ getMinimumNumSamplesRequiredInOutputSamples() [2/2]

int32_t com::avpkit::core::AudioResampler::getMinimumNumSamplesRequiredInOutputSamples ( int32_t  numSamples)
virtual

Get the minimum number of samples that must be placeable in an output set of samples in order for a resample with this resampler to succeed.

Parameters
numSamplesThe number of input samples.
Returns
The minimum number of samples, or < 0 on error.
Since
3.2

Implements com::avpkit::core::IAudioResampler.

Definition at line 232 of file AudioResampler.cpp.

234  {
235  int32_t retval = -1;
236 
237  try
238  {
239  if (numSamples < 0)
240  throw std::invalid_argument("numSamples < 0 not allowed");
241 
242  double conversionRatio = 1;
243  {
244  double top = mOSampleRate;
245  VS_ASSERT(top, "should never be zero");
246  double bot = mISampleRate;
247  VS_ASSERT(bot, "should never be zero");
248  conversionRatio = top/bot;
249  VS_ASSERT(conversionRatio > 0, "the variables used should have been checked on construction");
250  }
251  if (conversionRatio <= 0)
252  throw std::invalid_argument("programmer error");
253 
254  // FFMPEG's re-sample function doesn't let you specify the size of your
255  // output buffer, but does use up all the space you might expect
256  // plus 16-bytes as a lead-in/lead-out for it to seed the resampler.
257  // Hence, the hard-coded 16 here.
258  // NOTE: 16 might change IF the value of filters in the audio_resample
259  // method in libavcodec/resample.c changes.
260 #define VS_FFMPEG_AUDIO_RESAMPLER_LEADIN 16
261  retval =
262  (int32_t)((numSamples * conversionRatio)+VS_FFMPEG_AUDIO_RESAMPLER_LEADIN+0.5);
263  }
264  catch (std::invalid_argument & e)
265  {
266  VS_LOG_DEBUG("invalid argument: %s", e.what());
267  retval = -1;
268  }
269  catch (std::exception & e)
270  {
271  VS_LOG_DEBUG("Unknown exception: %s", e.what());
272  }
273 
274  return retval;
275  }

◆ getOutputChannels()

int com::avpkit::core::AudioResampler::getOutputChannels ( )
virtual

number of channels in output audio.

Returns
Number of channels we'll resample the output to.

Implements com::avpkit::core::IAudioResampler.

Definition at line 165 of file AudioResampler.cpp.

166  {
167  VS_ASSERT(swrContext, "no context");
168  return mOChannels;
169  }

◆ getOutputFormat()

IAudioSamples::Format com::avpkit::core::AudioResampler::getOutputFormat ( )
virtual

Get the sample format we expect to resample to.

Returns
the sample format for output.

Implements com::avpkit::core::IAudioResampler.

Definition at line 442 of file AudioResampler.cpp.

443  {
444  return mOFmt;
445  }

◆ getOutputRate()

int com::avpkit::core::AudioResampler::getOutputRate ( )
virtual

sample rate of output audio.

Returns
Sample Rate we'll resample the output to.

Implements com::avpkit::core::IAudioResampler.

Definition at line 172 of file AudioResampler.cpp.

173  {
174  VS_ASSERT(swrContext, "no context");
175  return mOSampleRate;
176  }

◆ isLinear()

bool com::avpkit::core::AudioResampler::isLinear ( )
virtual

Are we linearly interpolating between filters?

Returns
true if interpolating, false if just choosing closest.

Implements com::avpkit::core::IAudioResampler.

Definition at line 466 of file AudioResampler.cpp.

467  {
468  return mIsLinear;
469  }

◆ resample()

int com::avpkit::core::AudioResampler::resample ( IAudioSamples outputSamples,
IAudioSamples inputSamples,
int32_t  numSamples 
)
virtual

Re-sample up to numSamples from inputSamples to outputSamples.

This function re-samples the audio in inputSamples to have the same number of channels, and the same sample rate, as this IAudioResampler was initialized with.

Caller is responsible for making sure that the IAudioSamples object passed in has enough space. This object requires space for an additional 16-samples * output-channels per IAudioSamples passed in.

If the

outputSamples

is not large enough to fit the required resamples, then the IAudioResampler will attempt to allocate a new output buffer and override the buffer set on

outputSamples

. To ensure you have enough space in your output buffer, use the getMinimumNumSamplesRequiredInOutputSamples(int) method.

Parameters
outputSamples[out] The sample buffer we output to.
inputSamples[in] The samples we're going to re-sample.
numSamples[in] The number of samples from inputSamples to use. if 0, this defaults to inputSamples.getNumSamples().
Returns
Number of samples written to outputSamples, or <0 on error.

Implements com::avpkit::core::IAudioResampler.

Definition at line 278 of file AudioResampler.cpp.

281  {
282  int retval = -1;
283  AudioSamples* outSamples = static_cast<AudioSamples*>(pOutSamples);
284  AudioSamples* inSamples = static_cast<AudioSamples*>(pInSamples);
285  unsigned int sampleSize=0;
286 
287  try {
288  if (!outSamples)
289  throw std::invalid_argument("no output samples");
290 
291  if (outSamples == inSamples)
292  throw std::invalid_argument("resampling into the same IAudioSamples is not allowed");
293 
294  // null out the output samples.
295  outSamples->setComplete(false, 0, mOSampleRate, mOChannels,
296  mOFmt, Global::NO_PTS);
297 
298  if (inSamples)
299  {
300  if (!inSamples->isComplete())
301  throw std::invalid_argument("input samples are not complete");
302 
303  if (inSamples->getSampleRate() != mISampleRate)
304  throw std::invalid_argument("unexpected input sample rate");
305 
306  if (inSamples->getChannels() != mIChannels)
307  throw std::invalid_argument("unexpected # of input channels");
308 
309  if (inSamples->getFormat() != mIFmt)
310  throw std::invalid_argument("unexpected sample format");
311 
312  if (numSamples == 0)
313  numSamples = inSamples->getNumSamples();
314  else
315  numSamples = FFMIN(numSamples, inSamples->getNumSamples());
316  sampleSize = inSamples->getSampleBitDepth()/8;
317  } else {
318  numSamples = 0;
319  sampleSize = IAudioSamples::findSampleBitDepth(mIFmt)/8;
320  }
321 
322  int32_t neededSamples = getMinimumNumSamplesRequiredInOutputSamples(numSamples);
323  int32_t bytesPerOutputSample = mOChannels*IAudioSamples::findSampleBitDepth(mOFmt)/8;
324  int32_t neededBytes = neededSamples * bytesPerOutputSample; //av_samples_get_buffer_size(NULL, mOChannels, numSamples, (enum AVSampleFormat)mOFmt, 0);//
325  // This causes a buffer resize to occur if needed
326  if (outSamples->ensureCapacity(neededBytes) < 0)
327  throw std::runtime_error("attempted to resize output buffer but failed");
328 
329  int32_t outBufSize = outSamples->getMaxBufferSize();
330  int32_t gap = (neededSamples*bytesPerOutputSample)-outBufSize;
331 
332  if (gap > 0) {
333 // VS_LOG_ERROR("maxBufferSize: %d; neededSampleRoom: %d; sampleSize: %d; numSamples: %d; conversionRatio: %f;",
334 // (int32_t)outSamples->getMaxBufferSize(),
335 // neededSampleRoom,
336 // sampleSize,
337 // numSamples,
338 // conversionRatio);
339  (void) sampleSize; // to avoid a -Werror error
340  throw std::invalid_argument("not enough room in output buffer");
341  }
342  short * inBuf = inSamples ? inSamples->getRawSamples(0) : 0;
343 
344  short *outBuf = outSamples->getRawSamples(0);
345  if (!outBuf)
346  throw std::invalid_argument("could not get output bytes");
347 
348  VS_ASSERT(swrContext, "Should have been set at initialization");
349  if (!swrContext)
350  throw std::invalid_argument("programmer error");
351 
352  // Now we should be far enough along that we can safely try a resample.
353  retval = swr_convert(swrContext, (uint8_t**)&outBuf, swr_get_out_samples(swrContext, numSamples), (const uint8_t**)&inBuf, numSamples);
354 
355 #if 0
356  if (retval >0){
357  char string[2048*16+1];
358  unsigned int i=0;
359  for (i = 0; i < sizeof(string)-1; i++)
360  string[i] = 'X';
361 
362  bool allZero = true;
363 
364  for (i=0; i< FFMIN(numSamples, 2000);i++)
365  {
366  snprintf(string+(5*i), sizeof(string)-5*i, "%04hX.", inBuf[i]);
367  if (inBuf[i] != 0)
368  allZero = false;
369  }
370  VS_LOG_DEBUG("Input Buffer (%d): %s", numSamples, string);
371 
372  for (i=0; i< FFMIN((unsigned int)retval, 2000);i++)
373  {
374  snprintf(string+(9*i), sizeof(string)-9*i, "%04hX%04hX.",
375  outBuf[2*i], outBuf[2*i+1]);
376  if (outBuf[2*i] != 0 || outBuf[2*i+1] != 0)
377  allZero = false;
378  }
379  VS_LOG_DEBUG("Output Buffer (%d): %s", retval, string);
380  if (!allZero)
381  VS_LOG_DEBUG("Got an audio buffer with content");
382  }
383 #endif // 0
384 
385  if (retval >= 0)
386  {
387  // copy the Pts
388  int64_t pts = Global::NO_PTS;
389  if (inSamples)
390  {
391  pts = inSamples->getPts();
392  mNextPts = pts + IAudioSamples::samplesToDefaultPts(retval, mOSampleRate);
393  }
394  else
395  {
396  pts = mNextPts;
397  }
398  if (pts != Global::NO_PTS)
399  pts += mPtsOffset;
400 
401  outSamples->setComplete(true, retval,
402  mOSampleRate, mOChannels,
403  mOFmt,
404  pts);
405  int expectedSamples = 0;
406  if (inSamples)
407  {
408  double top = mOSampleRate;
409  double bottom = mISampleRate;
410  double sampleOnlyConverstionRatio = top / bottom;
411  expectedSamples = (int)(numSamples * sampleOnlyConverstionRatio);
412  }
413  else
414  {
415  VS_LOG_TRACE("Got null samples; outputted all cached and set pts offset from %lld to 0",
416  mPtsOffset);
417  expectedSamples = retval;
418  // and reset the offset
419  mPtsOffset = 0;
420  }
421 
422  if (retval != expectedSamples)
423  {
424  // we got a different number of samples than expected; we need to update
425  // our pts offset
426  int sampleDelta = retval - expectedSamples;
427  int64_t ptsDelta = IAudioSamples::samplesToDefaultPts(sampleDelta, mOSampleRate);
428  mPtsOffset += ptsDelta;
429  }
430  }
431  }
432  catch (std::invalid_argument & e)
433  {
434  VS_LOG_DEBUG("invalid argument: %s", e.what());
435  retval = -1;
436  }
437 
438  return retval;
439  }
static const int64_t NO_PTS
A value that means no time stamp is set for a given object.
Definition: Global.h:50
static int32_t findSampleBitDepth(Format format)
A convenience method that returns the # of bits in a given format.
static int64_t samplesToDefaultPts(int64_t samples, int sampleRate)
Converts a number of samples at a given sampleRate into Microseconds.

References com::avpkit::core::AudioSamples::ensureCapacity(), com::avpkit::core::IAudioSamples::findSampleBitDepth(), com::avpkit::core::AudioSamples::getChannels(), com::avpkit::core::AudioSamples::getFormat(), com::avpkit::core::AudioSamples::getMaxBufferSize(), com::avpkit::core::AudioSamples::getNumSamples(), com::avpkit::core::AudioSamples::getPts(), com::avpkit::core::AudioSamples::getSampleBitDepth(), com::avpkit::core::AudioSamples::getSampleRate(), com::avpkit::core::AudioSamples::isComplete(), com::avpkit::core::Global::NO_PTS, com::avpkit::core::IAudioSamples::samplesToDefaultPts(), and com::avpkit::core::AudioSamples::setComplete().


The documentation for this class was generated from the following files: