Durante el fin de semana he tropezado con un obstáculo para aprender a programar síntesis de audio en iOS. He estado desarrollando en iOS durante varios años, pero estoy entrando en el aspecto de síntesis de audio. En este momento, solo estoy programando aplicaciones de demostración para ayudarme a aprender los conceptos. En la actualidad, he podido construir y apilar ondas sinusoidales en un procesador de reproducción para unidades de audio sin problemas. Pero, quiero entender lo que está sucediendo en el renderizador para poder renderizar 2 ondas senoidales separadas en cada canal izquierdo y derecho. Actualmente, supongo que en mi sección de audio init que tendría que realizar los siguientes cambios:Unidad de audio iOS - Creación de ondas sinusoidales estéreo
Desde:
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = kSampleRate;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 2;
audioFormat.mBytesPerFrame = 2;
Para:
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = kSampleRate;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 4;
audioFormat.mBytesPerFrame = 4;
embargo, el procesador es un poco griego para mí . He estado trabajando en cualquier tutorial o código de ejemplo que pueda encontrar. Puedo hacer que las cosas funcionen para el contexto dado de una señal mono, pero no puedo hacer que el renderizador genere señales estéreo. Todo lo que quiero es una frecuencia distinta en un canal izquierdo y una frecuencia diferente en un canal derecho, pero la verdad es que no entiendo lo suficiente el renderizador como para que funcione. He intentado la función memcpy en mBuffers [0] y mbuffers [1], pero eso bloquea la aplicación. Mi render está debajo (actualmente contiene ondas sinusoidales apiladas, pero para el ejemplo estéreo puedo usar una onda de una frecuencia establecida en cada canal).
#define kOutputBus 0
#define kSampleRate 44100
//44100.0f
#define kWaveform (M_PI * 2.0f/kSampleRate)
OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
HomeViewController *me = (HomeViewController *)inRefCon;
static int phase = 1;
static int phase1 = 1;
for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) {
int samples = ioData->mBuffers[i].mDataByteSize/sizeof(SInt16);
SInt16 values[samples];
float waves;
float volume=.5;
float wave1;
for(int j = 0; j < samples; j++) {
waves = 0;
wave1 = 0;
MyManager *sharedManager = [MyManager sharedManager];
wave1 = sin(kWaveform * sharedManager.globalFr1 * phase1)*sharedManager.globalVol1;
if (0.000001f > wave1) {
[me setFr1:sharedManager.globalFr1];
phase1 = 0;
//NSLog(@"switch");
}
waves += wave1;
waves += sin(kWaveform * sharedManager.globalFr2 * phase)*sharedManager.globalVol2;
waves += sin(kWaveform * sharedManager.globalFr3 * phase)*sharedManager.globalVol3;
waves += sin(kWaveform * sharedManager.globalFr4 * phase)*sharedManager.globalVol4;
waves += sin(kWaveform * sharedManager.globalFr5 * phase)*sharedManager.globalVol5;
waves += sin(kWaveform * sharedManager.globalFr6 * phase)*sharedManager.globalVol6;
waves += sin(kWaveform * sharedManager.globalFr7 * phase)*sharedManager.globalVol7;
waves += sin(kWaveform * sharedManager.globalFr8 * phase)*sharedManager.globalVol8;
waves += sin(kWaveform * sharedManager.globalFr9 * phase)*sharedManager.globalVol9;
waves *= 32767/9; // <--------- make sure to divide by how many waves you're stacking
values[j] = (SInt16)waves;
values[j] += values[j]<<16;
phase++;
phase1++;
}
memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16));
}
return noErr;
}
¡Gracias de antemano por cualquier ayuda!
Si el formato está intercalado (como sugiere su ASBD), las muestras estarán en un búfer alternando a la izquierda y a la derecha: 'LRLRLRLR'. Sin embargo, sería inusual tener un formato intercalado en una devolución de llamada, por lo general, el formato es el formato canónico para el sistema operativo. – sbooth
Gracias. De hecho, lo descubrí hace solo unos minutos. Sin embargo, está intercalado como dijiste. Tuve que encontrar la manera de recorrer la devolución de llamada para renderizar las ondas sinusoidales en distintos canales de L & R. ¡Gracias por la ayuda! – jwkerr
Hola jwkerr, esperaba poder hablar contigo para publicar tu función de representación. He intentado que la reproducción estéreo funcione por un tiempo y no puedo obtenerla. Gracias – VaporwareWolf