Durante il fine settimana ho colpito un ostacolo imparando come programmare la sintesi audio su iOS. Sto sviluppando su iOS da diversi anni, ma sto entrando nell'aspetto della sintesi audio. In questo momento, sto solo programmando app demo per aiutarmi ad imparare i concetti. Al momento sono stato in grado di creare e impilare le onde sinusoidali in un riproduttore di riproduzione per unità audio senza problemi. Ma, voglio capire cosa sta succedendo nel renderer in modo da poter rendere 2 onde sinusoidali separate in ciascun canale sinistro e destro. Attualmente, presumo che nella mia sezione audio init avrei bisogno di apportare le seguenti modifiche:Unità audio iOS - Creazione di onde sinusoidali stereo
Da:
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;
A:
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;
Ma, il renderer è un po 'greco per me . Ho lavorato su qualsiasi tutorial o codice di esempio che posso trovare. Posso far funzionare le cose per il contesto dato da un segnale mono, ma non posso fare in modo che il renderizzatore generi segnali stereo. Tutto ciò che voglio è una frequenza distinta in un canale sinistro e una frequenza diversa in un canale destro, ma onestamente non capisco abbastanza il renderer per farlo funzionare. Ho provato la funzione memcpy in mBuffers [0] e mbuffers [1], ma questo causa il crash dell'applicazione. Il mio rendering è sotto (al momento contiene onde sinusoidali impilate, ma per l'esempio stereo posso comunque usare solo un'onda di una frequenza impostata in ogni canale).
#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;
}
Grazie in anticipo per qualsiasi aiuto!
Se il formato è interlacciato (come suggerisce il vostro ASBD), poi i campioni saranno in un'alternanza di buffer destro e sinistro: 'LRLRLRLR'. Tuttavia, sarebbe insolito avere un formato interlacciato in un callback, in genere il formato è il formato canonico per il sistema operativo. – sbooth
Grazie. In realtà ho appena capito tutto solo pochi minuti fa. È interlacciato come hai detto tu, però. Ho dovuto capire come passare attraverso il callback per rendere le onde sinusoidali in canali L & R distinti. Grazie per l'aiuto però !! – jwkerr
Ciao jwkerr, speravo che potessi parlarti di postare la tua funzione di rendering. Ho cercato di ottenere il rendering stereo lavorando per un po 'e non riesco a capirlo. Grazie – VaporwareWolf