[英]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.