[英]Writing buffer of audio samples to aac file using ExtAudioFileWrite for iOS
[英]How to skip samples in an audio buffer on iOS
我正在尝试跳过或缩短iOS上音频播放的静音。 使用RemoteIO,我将以下代码段用于消除静音的逻辑。 但是,它不能正常工作。 根据代码,我希望可以从samples
消除静音,并使音频以最小的速度播放(因为样本会被删除)。 但是,相反,我有时会听到奇怪的弹出声/咔嗒声,并且音频定时是相同的(什么都不会跳过,就像消除了静音一样)。
有什么想法我做错了吗? 这是错误的做法吗?
// original samples are stored in renderBufferList
// loop through the samples and replace anything less than amplitudeThreshold
// with the next "non-silent" sample
SInt16 *samples = renderBufferList->mBuffers[0].mData;
int sampleCount = renderBufferList->mBuffers[0].mDataByteSize / sizeof(SInt16);
int currentSampleIndex = 0;
int amplitudeThreshold = 15;
int channels = 2;
for (int i = 0; i < sampleCount; i+=channels) {
SInt16 sampleL = samples[i];
SInt16 sampleR = samples[i+1];
// check if amplitude of sample is > amplitudeThreshold
if (abs(sampleL) > amplitudeThreshold || abs(sampleR) > amplitudeThreshold) {
// set samples and increase to next sample set
samples[currentSampleIndex] = sampleL;
samples[currentSampleIndex+1] = sampleR;
currentSampleIndex+=channels;
}
}
// how many bytes should be in non-amplitudeThreshold samples
int bytesToCopy = currentSampleIndex * sizeof(SInt16);
if (bytesToCopy > 0) {
// store samples in circular buffer
TPCircularBufferProduceBytes(&circularBuffer, samples, bytesToCopy);
} else {
// set buffer to silence
memset((SInt16*)inIoData->mBuffers[0].mData, 0, bytesToCopy);
return noErr;
}
int outputDataByteSize = inIoData->mBuffers[0].mDataByteSize;
SInt16 *outputBuffer = (SInt16*)inIoData->mBuffers[0].mData;
// if circularBuffer is filled more than outputDataByteSize * 10 (large buffer)
if (circularBuffer.fillCount > outputDataByteSize * 10) {
int32_t availableBytes;
SInt16 *buffer = TPCircularBufferTail(&circularBuffer, &availableBytes);
if(buffer == NULL) {
NSLog(@"circular buffer is empty. end of track.");
return noErr;
}
int numBytes = MIN(bytesToCopy, availableBytes);
memcpy(outputBuffer, buffer, numBytes);
// consume (remove) bytes from circular buffer that are being copied to output buffer
TPCircularBufferConsume(&circularBuffer, numBytes);
}
else {
NSLog(@"buffering");
memset(targetBuffer, 0, outputDataByteSize);
return noErr;
}
查看静默检测逻辑(我不是IOS / swift程序员),似乎您正在逐个样本地定义静默。 这不是音频的工作方式,基本上您要做的就是剪切波形中低于振幅阈值的部分-导致咔嗒声,因为波形的上部仍然存在,所以静音/低振幅数据仍然有些在那里(尽管已损坏)。
我建议计算音频帧的振幅,即样本的一些子集,而不是硬切成0,而是线性上/下移动以消除咔嗒声。
还有一点,您的样本采用什么格式? -1:1个PCM? 如果您还没有这样做,那么基于分贝而不是原始数据来检测沉默也是值得的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.