Como usar uma unidade de áudio no iPhone
-
20-08-2019 - |
Pergunta
Eu estou procurando uma maneira de alterar o tom de áudio gravado como ele é salvo em disco, ou reproduzidas (em tempo real). Eu entendo Áudio Units pode ser usado para isso. O apoio ofertas iPhone limitado para Unidades de áudio (por exemplo, não é possível criar uso unidades / áudio personalizados, tanto quanto eu posso dizer), mas vários out-of-the-box unidades de áudio estão disponíveis, um dos quais é AUPitch.
Como exatamente eu iria usar uma unidade de áudio (especificamente AUPitch)? Você ligá-lo em uma fila de áudio de alguma forma? É possível unidades de áudio cadeia juntos (por exemplo, para adicionar simultaneamente um efeito de eco e uma mudança de tom)?
EDIT: Depois de inspecionar os cabeçalhos iPhone SDK (acho AudioUnit.h, eu não estou na frente de um Mac no momento), notei que AUPitch está comentada. Por isso não se parece com AUPitch está disponível no iPhone depois de tudo. choram choram
Apple parece ter melhor organizado sua documentação iPhone SDK no developer.apple.com da tarde - agora é mais difícil encontrar referências a AUPitch, etc.
Dito isto, eu ainda estou interessado em respostas de qualidade sobre o uso de unidades de áudio (em geral) sobre o iPhone.
Solução
Existem alguns recursos muito bons aqui ( http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/ ) para utilizar a unidade de áudio do RemoteIO. Na minha experiência de trabalho com unidades de áudio no iPhone, eu descobri que eu possa implementar uma transformação manualmente na função de retorno. Ao fazer isso, você pode achar que resolve o seu problema.
Outras dicas
Quanto alterar a afinação no iPhone, OpenAL é o caminho a percorrer. Confira a classe SoundManager disponível a partir www.71squared.com para um grande exemplo de um motor de som OpenAL que suportes campo.
- (void)modifySpeedOf:(CFURLRef)inputURL byFactor:(float)factor andWriteTo:(CFURLRef)outputURL {
ExtAudioFileRef inputFile = NULL;
ExtAudioFileRef outputFile = NULL;
AudioStreamBasicDescription destFormat;
destFormat.mFormatID = kAudioFormatLinearPCM;
destFormat.mFormatFlags = kAudioFormatFlagsCanonical;
destFormat.mSampleRate = 44100 * factor;
destFormat.mBytesPerPacket = 2;
destFormat.mFramesPerPacket = 1;
destFormat.mBytesPerFrame = 2;
destFormat.mChannelsPerFrame = 1;
destFormat.mBitsPerChannel = 16;
destFormat.mReserved = 0;
ExtAudioFileCreateWithURL(outputURL, kAudioFileCAFType,
&destFormat, NULL, kAudioFileFlags_EraseFile, &outputFile);
ExtAudioFileOpenURL(inputURL, &inputFile);
//find out how many frames is this file long
SInt64 length = 0;
UInt32 dataSize2 = (UInt32)sizeof(length);
ExtAudioFileGetProperty(inputFile,
kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length);
SInt16 *buffer = (SInt16*)malloc(kBufferSize * sizeof(SInt16));
UInt32 totalFramecount = 0;
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = 1;
bufferList.mBuffers[0].mData = buffer; // pointer to buffer of audio data
bufferList.mBuffers[0].mDataByteSize = kBufferSize *
sizeof(SInt16); // number of bytes in the buffer
while(true) {
UInt32 frameCount = kBufferSize * sizeof(SInt16) / 2;
// Read a chunk of input
ExtAudioFileRead(inputFile, &frameCount, &bufferList);
totalFramecount += frameCount;
if (!frameCount || totalFramecount >= length) {
//termination condition
break;
}
ExtAudioFileWrite(outputFile, frameCount, &bufferList);
}
free(buffer);
ExtAudioFileDispose(inputFile);
ExtAudioFileDispose(outputFile);
}
ele vai mudar campo com base em fator
Eu usei a unidade áudio NewTimePitch para este antes, a descrição do componente de áudio para que seja
var newTimePitchDesc = AudioComponentDescription(componentType: kAudioUnitType_FormatConverter,
componentSubType: kAudioUnitSubType_NewTimePitch,
componentManufacturer: kAudioUnitManufacturer_Apple,
componentFlags: 0,
componentFlagsMask: 0)
então você pode mudar o parâmetro de campo com uma chamada AudioUnitSetParamater. Por exemplo, este muda o tom por -1000 centavos
err = AudioUnitSetParameter(newTimePitchAudioUnit,
kNewTimePitchParam_Pitch,
kAudioUnitScope_Global,
0,
-1000,
0)
Os parâmetros para esta unidade de áudio são os seguintes
// Parameters for AUNewTimePitch
enum {
// Global, rate, 1/32 -> 32.0, 1.0
kNewTimePitchParam_Rate = 0,
// Global, Cents, -2400 -> 2400, 1.0
kNewTimePitchParam_Pitch = 1,
// Global, generic, 3.0 -> 32.0, 8.0
kNewTimePitchParam_Overlap = 4,
// Global, Boolean, 0->1, 1
kNewTimePitchParam_EnablePeakLocking = 6
};
mas você só precisará alterar o parâmetro de campo para seus propósitos. Para um guia sobre como implementar este referir-se a resposta de Justin