gpt4 book ai didi

ios - iOS音频单元将声音剪切到某个频率以上

转载 作者:行者123 更新时间:2023-12-01 16:43:55 24 4
gpt4 key购买 nike

我在接收声音(UDP WiFi)时遇到了一些问题,我想尽可能地清除它。因此,一开始我要在某些频率以上截断声音。显然,我从套接字获取了原始数据,然后将其复制到输出缓冲区。我确信应该在那儿进行精确的切断。

你可以建议我吗?

我当前的回调代码

static OSStatus outputCallback(void *udata,
AudioUnitRenderActionFlags *flags,
const AudioTimeStamp *ts,
UInt32 busnum,
UInt32 nframes,
AudioBufferList *buflist) {

NXAudioDevice *dev = (__bridge NXAudioDevice *) udata;
AudioBuffer *buf = buflist->mBuffers;
// Here I get new audioBufferData
NSData *data = [dev getAudioData];
if (!data) {
buf->mDataByteSize = 0;
return -1;
} else {
[data getBytes:buf->mData length:buf->mDataByteSize];
}

return noErr;
}

更新

我为渲染回调找到了类似的东西,atm我想为outputCallback添加类似的东西。
OSStatus RenderFFTCallback (void                    *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
RIOInterface* THIS = (RIOInterface *)inRefCon;
COMPLEX_SPLIT A = THIS->A;
void *dataBuffer = THIS->dataBuffer;
float *outputBuffer = THIS->outputBuffer;
FFTSetup fftSetup = THIS->fftSetup;

uint32_t log2n = THIS->log2n;
uint32_t n = THIS->n;
uint32_t nOver2 = THIS->nOver2;
uint32_t stride = 1;
int bufferCapacity = THIS->bufferCapacity;
SInt16 index = THIS->index;

AudioUnit rioUnit = THIS->ioUnit;
OSStatus renderErr;
UInt32 bus1 = 1;

renderErr = AudioUnitRender(rioUnit, ioActionFlags,
inTimeStamp, bus1, inNumberFrames, THIS->bufferList);
if (renderErr < 0) {
return renderErr;
}

// Fill the buffer with our sampled data. If we fill our buffer, run the
// fft.
int read = bufferCapacity - index;
if (read > inNumberFrames) {
memcpy((SInt16 *)dataBuffer + index, THIS->bufferList->mBuffers[0].mData, inNumberFrames*sizeof(SInt16));
THIS->index += inNumberFrames;
} else {
// If we enter this conditional, our buffer will be filled and we should
// perform the FFT.
memcpy((SInt16 *)dataBuffer + index, THIS->bufferList->mBuffers[0].mData, read*sizeof(SInt16));

// Reset the index.
THIS->index = 0;

/*************** FFT ***************/
// We want to deal with only floating point values here.
ConvertInt16ToFloat(THIS, dataBuffer, outputBuffer, bufferCapacity);

/**
Look at the real signal as an interleaved complex vector by casting it.
Then call the transformation function vDSP_ctoz to get a split complex
vector, which for a real signal, divides into an even-odd configuration.
*/
vDSP_ctoz((COMPLEX*)outputBuffer, 2, &A, 1, nOver2);

// Carry out a Forward FFT transform.
vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_FORWARD);

// The output signal is now in a split real form. Use the vDSP_ztoc to get
// a split real vector.
vDSP_ztoc(&A, 1, (COMPLEX *)outputBuffer, 2, nOver2);

// Determine the dominant frequency by taking the magnitude squared and
// saving the bin which it resides in.
float dominantFrequency = 0;
int bin = -1;
for (int i=0; i<n; i+=2) {
float curFreq = MagnitudeSquared(outputBuffer[i], outputBuffer[i+1]);
if (curFreq > dominantFrequency) {
dominantFrequency = curFreq;
bin = (i+1)/2;
}
}
memset(outputBuffer, 0, n*sizeof(SInt16));

// Update the UI with our newly acquired frequency value.
[THIS->listener frequencyChangedWithValue:bin*(THIS->sampleRate/bufferCapacity)];
printf("Dominant frequency: %f bin: %d \n", bin*(THIS->sampleRate/bufferCapacity), bin);


}

return noErr;
}

最佳答案

这并不像看起来那样容易。一种方法是使用FFT将数据移至频域,消除高频,然后使用反向FFT移回时域。 iOS中提供了FFT功能。请参阅使用傅立叶变换vDSP Programming Guide

一个起点是苹果的示例代码aurioTouch2

回答评论:字节没有频率,只有振幅(响度)。基本上,振幅采样具有周期性频率,例如44100Hz。天真的低通音频方法是删除所有其他采样,但这不起作用,它只是将较高的频率混叠为较低的频率。

关于ios - iOS音频单元将声音剪切到某个频率以上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21755629/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com