2016-04-14 15 views
1

Ich habe eine Frage dazu, was Ich denke, kocht auf C-Syntax und Speicher Überlegungen. Ich habe einen Callback in einer Objective-C-Klasse, die Audio verarbeitet, und eines der Argumente lautet bufferListInOut. Es stellt ein Mono-Audiosignal dar, das ich in Stereo konvertieren möchte. Hier ist mein Code:Erweiterung eines Arrays innerhalb einer Struktur in C

static void tap_ProcessCallback(MTAudioProcessingTapRef tap, 
          CMItemCount numberFrames, 
          MTAudioProcessingTapFlags flags, 
          AudioBufferList *bufferListInOut, 
          CMItemCount *numberFramesOut, 
          MTAudioProcessingTapFlags *flagsOut){ 

    // Retrieve mono audio data into bufferListInOut 
    MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, NULL, NULL, NULL); 

    // Copy the mono channel's data 
    float *channelLeft = malloc(numberFrames * sizeof(float)); 
    channelLeft = bufferListInOut->mBuffers[0].mData; 

    // Attempt to create a second channel which is (currently) a copy of the first 
    bufferListInOut->mNumberBuffers = 2; // 2 for stereo, 1 for mono 
    bufferListInOut->mBuffers[1].mNumberChannels = 1; 
    bufferListInOut->mBuffers[1].mDataByteSize = numberFrames * sizeof(Float32); 
    bufferListInOut->mBuffers[1].mData = channelLeft; 

    // Set number of frames out 
    *numberFramesOut = numberFrames; 
} 

Einige Anmerkungen:

  • In diesem Code der neue Kanal ist nur eine Kopie des Originals, aber in der Praxis wird es einige Verarbeitung unterzogen werden.
  • Die Namensgebung ist ein wenig seltsam, aber mNumberBuffers ist in der Tat sein soll 2 und mNumberChannels gemeint 1.

Dieser stürzt mit einem EXC_BAD_ACCESS Fehler werden auf einem Rendering der Linie Faden nach unten. Also, meine Frage ist, was ist der richtige Weg, um einen neuen Puffer zu dieser Struktur hinzuzufügen? Ich beschäftige mich nicht allzu oft mit C, daher bin ich mir sicher, dass ich hier einige Grundlagen vermisse. Alle Hinweise dazu wären großartig. Danke fürs Lesen.

+0

Was ist Ihre Frage? Es gibt keinen einzigen in diesem Post. – Sanuuu

+1

Das ist eine komplexe Sache, aber Sie vergeben Speicher und ordnen ihn "channelLeft" zu und weisen dann sofort "channelLeft" neu zu, was zu einem Speicherverlust führt. Ich denke du willst 'memcpy (channelLeft, bufferListInOut-> mBuffers [0] .mData, numberFrames * sizeof (float));'. – trojanfoe

+0

@Sanuuu Danke für den Kommentar. Ich habe gerade die Frage geklärt. – Rogare

Antwort

3

Sie können nicht tun, was Sie versuchen, zumindest in der Art, wie Sie es versuchen. Der Typ AudioBufferList deklariert als:

struct AudioBufferList { UInt32 mNumberBuffers; AudioBuffer mBuffers[1]; }; 

Dies ist ein klassisches C-Muster für eine variabler Größe Struktur. Um eine Struktur für N zu schaffen puffert einen einzelne Speicherblock mit der Größe zugeordnet wird:

sizeof(UInt32) + N * sizeof(AudioBuffer) 

Die Adresse dieser Blöcke zu einer AudioBufferList * Variablen zugewiesen wird, und das Feld mNumberBuffers Satz N. Sie kann nicht erhöhen einfach die mNumberBuffers, um die Größe des Arrays zu erhöhen, stattdessen müssen Sie entweder eine neue vollständige Struktur zuweisen, oder realloc die vorhandene - realloc erhöht die Größe des Speicherblocks wenn möglich oder eine neue Zuweisung und kopiert die vorhandene Daten hinein, wenn nicht.

Angesichts Ihrer tap_ProcessCallback()-Funktion ist ein AudioBuuferList * Wert übergeben und gibt keinen zurück, es gibt keine Möglichkeit, es kann die Größe der Struktur ändern (d. H. Die Anzahl der Puffer) es ist übergeben.

Wie in den Kommentaren erwähnt, machen Sie auch Zeigerzuweisung, wenn Sie beabsichtigen, Speicher zu kopieren - siehe memcpy und Freunde.

Sie brauchen also ein Redesign - Ihr Ziel ist möglich, nur nicht wie und wo Sie es versucht haben.

HTH

+0

Hallo @CRD, danke für diese Erklärung, sehr hilfreich! Nur um sicherzustellen, dass ich folge, wenn du sagst "es gibt keine Möglichkeit [tap_ProcessCallback()] kann die Größe der Struktur ändern ... brauche ein Redesign" sagst du das mit den Funktionsargumenten so wie sie sind (was wir leider nicht kontrollieren können) über), ist es nicht möglich, die Anzahl der Puffer zu ändern? – Rogare

+1

Korrigieren. Der Funktion wird die Adresse der Anrufer 'AudioBufferList' übergeben. Wie geschrieben, hat es keine Möglichkeit, den Anruferwert für diese Adresse in den eines neuen, vergrößerten struct zu ändern. – CRD

+0

Sie können den Aufrufer-Wert ändern, wenn Sie den Funktionsparameter in 'AudioBufferList ** bufferListInOut' ändern (natürlich Code innerhalb aktualisieren und überall, wo die Funktion aufgerufen wird). Nun ... Ich habe immer noch den Fehler -50 (kAudio_ParamError). – tontonCD

Verwandte Themen