Erstellen des Echoeffekts
Sie müssen zuerst den Code aus dem Assistentenbeispiel entfernen, das die Audiodaten skaliert. Entfernen Sie im 8-Bit-Abschnitt den folgenden Code:
// Apply scale factor to sample.
i = int( ((double) i) * m_dwDelayTime );
(Denken Sie daran, dass m _ fScaleFactor durch m _ dwDelayTime ersetzt wurde.)
Entfernen Sie im 16-Bit-Abschnitt den folgenden Code:
// Apply scale factor to sample.
i = int( ((double) i) * m_dwDelayTime );
Die Implementierung von DoProcessOutput, die vom Beispielcode des Plug-In-Assistenten bereitgestellt wird, erstellt eine while-Schleife, die einmal für jedes Beispiel im Eingabepuffer durchläuft, der von Windows Media Player bereitgestellt wird. Diese Schleife funktioniert für 8-Bit- und 16-Bit-Audio auf die gleiche Weise, obwohl für jede eine separate Schleife erforderlich ist. In jedem Fall wird die Schleife mit dem folgenden Test initiiert:
while (dwSamplesToProcess--)
Innerhalb der Schleife sind die Verarbeitungsroutinen für 8-Bit- und 16-Bit-Audio sehr ähnlich. Der Hauptunterschied besteht darin, dass der Code im 8-Bit-Abschnitt den Bereich der Datenwerte in -128 bis 127 ändert und dann den Bereich wieder zurück konvertiert, bevor die Daten in den Ausgabepuffer geschrieben werden. Dies ist wichtig, um die Symmetrie der Audiowellenform während der Verarbeitung beizubehalten.
Jetzt können Sie beginnen, Code in der Verarbeitungsschleife hinzuzufügen und zu ersetzen.
Abrufen eines Beispiels aus dem Eingabepuffer
Während jeder Iteration der Schleife wird ein einzelnes Beispiel aus dem Eingabepuffer abgerufen. Bei 8-Bit-Audio wird das Beispiel in den neuen Bereich verschoben, und dann wird der Zeiger auf den Eingabepuffer auf das nächste Beispiel erweitert. Der folgende Code stammt aus dem Plug-In-Assistenten:
// Get the input sample and normalize to -128 .. 127
int i = (*pbInputData++) - 128;
Bei 16-Bit-Audio ist der Prozess mit Ausnahme der Normalisierung identisch:
// Get the input sample.
int i = *pwInputData++;
Denken Sie daran, dass die Zeiger im 16-Bit-Code in den Typ short konvertiert wurden.
Abrufen eines Beispiels aus dem Verzögerungspuffer
Rufen Sie als Nächstes ein einzelnes Beispiel aus dem Verzögerungspuffer ab. Für 8-Bit-Code werden die Verzögerungsbeispiele in ihrem nativen Bereich von 0 bis 255 gespeichert. Der folgende Code, den Sie hinzufügen müssen, ruft ein 8-Bit-Verzögerungsbeispiel ab:
// Get the delay sample and normalize to -128 .. 127
int delay = m_pbDelayPointer[0] - 128;
Bei 16-Bit-Audio ist der Prozess ähnlich:
// Get the delay sample.
int delay = *pwDelayPointer;
Schreiben des Eingabebeispiels in den Verzögerungspuffer
Nun müssen Sie das Eingabebeispiel im Verzögerungspuffer an dem Speicherort speichern, von dem Sie das Verzögerungsbeispiel abgerufen haben. Im Folgenden sehen Sie den Code, den Sie für 8-Bit-Audio hinzufügen müssen:
// Write the input sample into the delay buffer.
m_pbDelayPointer[0] = i + 128;
Dies ist der Code, der für den 16-Bit-Abschnitt hinzugefügt werden soll:
// Write the input sample to the delay buffer.
*pwDelayPointer = i;
Verschieben des Verzögerungspufferzeigers
Nachdem die Arbeit im Verzögerungspuffer für diese Iteration abgeschlossen ist, können Sie den verschiebbaren Zeiger auf den Verzögerungspuffer verschieben. Wenn der Zeiger das Ende des Kreispuffers erreicht, müssen Sie seinen Wert so ändern, dass er auf den Kopf des Puffers zeigt. Verwenden Sie den folgenden Code, um dies für 8-Bit-Audio zu tun:
// Increment the delay pointer.
// If it has passed the end of the buffer,
// then move it to the head of the buffer.
if (++m_pbDelayPointer > pbEOFDelayBuffer)
m_pbDelayPointer = m_pbDelayBuffer;
Hier ist der Code für den 16-Bit-Abschnitt:
// Increment the local delay pointer.
// If it is past the end of the buffer,
// then move it to the head of the buffer.
if (++pwDelayPointer > pwEOFDelayBuffer)
pwDelayPointer = pwDelayBuffer;
Da der Zeiger im 16-Bit-Abschnitt tatsächlich eine Kopie der Membervariablen ist, müssen Sie daran denken, den Wert in der Membervariablen mit der neuen Adresse zu aktualisieren. Wenn Sie dies nicht tun, zeigt der Verzögerungspufferzeiger wiederholt auf den Kopf des Puffers, und Ihr Echoeffekt funktioniert nicht wie erwartet. Fügen Sie dem 16-Bit-Abschnitt den folgenden Code hinzu:
// Move the global delay pointer.
m_pbDelayPointer = (BYTE *) pwDelayPointer;
Kombinieren des Eingabebeispiels mit dem Verzögerungsbeispiel
An dieser Stelle verwenden Sie die Werte für Vernetzungsmischung und Mischungstrocken, um das endgültige Ausgabebeispiel zu erstellen. Sie multiplizieren jede Stichprobe einfach mit dem Gleitkommawert, der den Prozentsatz des endgültigen Signals für die Stichprobe darstellt. Multiplizieren Sie das Eingabebeispiel mit dem in m _ fDryMix gespeicherten Wert. Multiplizieren Sie die Verzögerungsstichprobe mit dem in m _ fWetMix gespeicherten Wert. Fügen Sie dann die beiden Werte hinzu. Der Code, den Sie hinzufügen müssen, ist für die Abschnitte 8 Bit und 16 Bit identisch:
// Mix the delay with the dry signal.
i = (int)((i * m_fDryMix ) + (delay * m_fWetMix));
Schreiben der Daten in den Ausgabepuffer
Kopieren Sie abschließend das gemischte Beispiel in den Ausgabepuffer, und schreiten Sie dann den Ausgabepufferzeiger voran. Für 8-Bit-Audio verwendet der Plug-In-Assistent den folgenden Code, um das Beispiel an den ursprünglichen Bereich zurückzugeben:
// Convert back to 0..255 and write to output buffer.
*pbOutputData++ = (BYTE)(i + 128);
Für 16-Bit-Audio verwendet der Assistent den folgenden Code als letzten Schritt in der Verarbeitungsschleife:
// Write to output buffer.
*pwOutputData++ = i;