From 908a8532230fa62582fcf95f941facb5178350eb Mon Sep 17 00:00:00 2001 From: Seiji Emery Date: Fri, 7 Sep 2012 16:15:19 -0700 Subject: [PATCH] Minor changes: added an additional audio buffer (captures audio input), with a corresponding read method. This buffer is optional, and toggleable via a preprocessor macro. Also added const-correctness for Audio write methods. --- audio.cpp | 92 ++++++++++++++++-- audio.h | 46 +++++++-- interface.xcodeproj/project.pbxproj | 8 ++ .../UserInterfaceState.xcuserstate | Bin 26817 -> 25873 bytes 4 files changed, 128 insertions(+), 18 deletions(-) diff --git a/audio.cpp b/audio.cpp index 26ccb19087..13f6d54ec9 100644 --- a/audio.cpp +++ b/audio.cpp @@ -8,7 +8,7 @@ /** * @file audio.cpp - * Low level audio i/o wrapper around portaudio. + * Low level audio i/o portaudio wrapper. * * @author Seiji Emery * @@ -56,25 +56,56 @@ int audioCallback (const void *inputBuffer, float *input = (float*)inputBuffer; float *output = (float*)outputBuffer; - if (input != NULL) { + #if WRITE_AUDIO_INPUT_TO_OUTPUT + if (input != NULL) {// && Audio::writeAudioInputToOutput) { // combine input into data buffer // temp variables (frames and bufferPos need to remain untouched so they can be used in the second block of code) unsigned int f = (unsigned int)frames, p = data->bufferPos; for (; p < data->bufferLength && f > 0; --f, ++p) { + #if WRITE_AUDIO_INPUT_TO_BUFFER + data->buffer[p].l += + data->inputBuffer[p].l = (*input++) * data->inputGain; + data->buffer[p].r += + data->inputBuffer[p].r = (*input++) * data->inputGain; + #else data->buffer[p].l += (*input++) * data->inputGain; data->buffer[p].r += (*input++) * data->inputGain; + #endif } if (f > 0) { // handle data->buffer wraparound for (p = 0; f > 0; --f, ++p) { + #if WRITE_AUDIO_INPUT_TO_BUFFER + data->buffer[p].l += + data->inputBuffer[p].l = (*input++) * data->inputGain; + data->buffer[p].r += + data->inputBuffer[p].r = (*input++) * data->inputGain; + #else data->buffer[p].l += (*input++) * data->inputGain; data->buffer[p].r += (*input++) * data->inputGain; + #endif + } + } + } + #elif WRITE_AUDIO_INPUT_TO_BUFFER + if (input != NULL) {// && Audio::writeAudioInputToBuffer) { + unsigned int f = (unsigned int)frames, + p = data->bufferPos; + for (; p < data->bufferLength && f > 0; --f, ++p) { + data->inputBuffer[p].l = (*input++) * data->inputGain; + data->inputBuffer[p].r = (*input++) * data->inputGain; + } + if (f > 0) { + // handle data->buffer wraparound + for (p = 0; f > 0; --f, ++p) { + data->inputBuffer[p].l = (*input++) * data->inputGain; + data->inputBuffer[p].r = (*input++) * data->inputGain; } } } - + #endif // Write data->buffer into outputBuffer if (data->bufferPos + frames >= data->bufferLength) { // wraparound: write first section (end of buffer) first @@ -143,7 +174,8 @@ error: */ bool Audio::terminate () { - if (!initialized) return; + if (!initialized) + return true; initialized = false; // err = Pa_StopStream(stream); // if (err != paNoError) goto error; @@ -171,7 +203,9 @@ error: * @param[in] left Left channel of the audio stream. * @param[in] right Right channel of the audio stream. */ -void Audio::writeAudio (unsigned int offset, unsigned int length, float *left, float *right) { +void Audio::writeAudio (unsigned int offset, unsigned int length, float const *left, float const *right) { + if (data->buffer == NULL) + return; if (length > data->bufferLength) { fprintf(stderr, "Audio::writeAudio length exceeded (%d). Truncating to %d.\n", length, data->bufferLength); length = data->bufferLength; @@ -200,7 +234,9 @@ void Audio::writeAudio (unsigned int offset, unsigned int length, float *left, f * @param[in] left Left component. * @param[in] right Right component. */ -void Audio::writeTone (unsigned int offset, unsigned int length, float left, float right) { +void Audio::writeTone (unsigned int offset, unsigned int length, float const left, float const right) { + if (data->buffer == NULL) + return; if (length > data->bufferLength) { fprintf(stderr, "Audio::writeTone length exceeded (%d). Truncating to %d.\n", length, data->bufferLength); length = data->bufferLength; @@ -230,7 +266,9 @@ void Audio::writeTone (unsigned int offset, unsigned int length, float left, flo * @param[in] left Left channel of the audio stream. * @param[in] right Right channel of the audio stream. */ -void Audio::addAudio (unsigned int offset, unsigned int length, float *left, float *right) { +void Audio::addAudio (unsigned int offset, unsigned int length, float const *left, float const *right) { + if (data->buffer == NULL) + return; if (length > data->bufferLength) { fprintf(stderr, "Audio::addAudio length exceeded (%d). Truncating to %d.\n", length, data->bufferLength); length = data->bufferLength; @@ -260,7 +298,9 @@ void Audio::addAudio (unsigned int offset, unsigned int length, float *left, flo * @param[in] left Left component. * @param[in] right Right component. */ -void Audio::addTone (unsigned int offset, unsigned int length, float left, float right) { +void Audio::addTone (unsigned int offset, unsigned int length, float const left, float const right) { + if (data->buffer == NULL) + return; if (length > data->bufferLength) { fprintf(stderr, "Audio::writeTone length exceeded (%d). Truncating to %d.\n", length, data->bufferLength); length = data->bufferLength; @@ -286,6 +326,8 @@ void Audio::addTone (unsigned int offset, unsigned int length, float left, float * @param[in] length Length of section to clear. */ void Audio::clearAudio(unsigned int offset, unsigned int length) { + if (data->buffer == NULL) + return; if (length > data->bufferLength) { fprintf(stderr, "Audio::clearAudio length exceeded (%d). Truncating to %d.\n", length, data->bufferLength); length = data->bufferLength; @@ -304,7 +346,39 @@ void Audio::clearAudio(unsigned int offset, unsigned int length) { } } - +/** + * Read audio input into the target buffer. + * @param[in] offset Offset from the start of the input audio buffer to read from. + * @param[in] length Length of the target buffer. + * @param[out] left Left channel of the target buffer. + * @param[out] right Right channel of the target buffer. + */ +void Audio::readAudioInput (unsigned int offset, unsigned int length, float *left, float *right) { +#if WRITE_AUDIO_INPUT_TO_BUFFER + if (data->inputBuffer == NULL) + return; + if (length + offset > data->bufferLength) { + fprintf(stderr, "Audio::readAudioInput length exceeded (%d + %d). Truncating to %d + %d.\n", offset, length, offset, data->bufferLength - offset); + length = data->bufferLength - offset; + } + unsigned int p = data->bufferPos + offset; + if (p > data->bufferLength) + p -= data->bufferLength; + for (; p < data->bufferLength && length > 0; --length, ++p) { + *left++ = data->inputBuffer[p].l; + *right++ = data->inputBuffer[p].r; + } + if (length > 0) { + p = 0; + for (; length > 0; --length, ++p) { + *left++ = data->inputBuffer[p].l; + *right++ = data->inputBuffer[p].r; + } + } +#else + return; +#endif +} diff --git a/audio.h b/audio.h index 27915648dc..f626b8afde 100644 --- a/audio.h +++ b/audio.h @@ -13,6 +13,24 @@ // Note: main documentation in audio.cpp +/** + * If enabled, direct the audio callback to write the audio input buffer + * directly into the audio output buffer. + */ +#define WRITE_AUDIO_INPUT_TO_OUTPUT 1 +/** + * If enabled, create an additional buffer to store audio input + * and direct the audio callback to write the audio input to this buffer. + */ +#define WRITE_AUDIO_INPUT_TO_BUFFER 0 + +// Note: I initially used static const bools within the Audio class and normal +// 'if' blocks instead of preprocessor - under the assumption that the compiler +// would optimize out the redundant code. +// However, as that apparently did not work (for some reason or another - even +// with full compiler optimization turned on), I've switched to using preprocessor +// macros instead (which is probably faster anyways (at compile-time)). + /** * Low level audio interface. * @@ -30,12 +48,16 @@ public: static bool terminate (); // Write methods: write to internal audio buffer. - static void writeAudio (unsigned int offset, unsigned int length, float *left, float *right); - static void addAudio (unsigned int offset, unsigned int length, float *left, float *right); - static void writeTone (unsigned int offset, unsigned int length, float left, float right); - static void addTone (unsigned int offset, unsigned int length, float left, float right); + static void writeAudio (unsigned int offset, unsigned int length, float const *left, float const *right); + static void addAudio (unsigned int offset, unsigned int length, float const *left, float const *right); + static void writeTone (unsigned int offset, unsigned int length, float const left, float const right); + static void addTone (unsigned int offset, unsigned int length, float const left, float const right); static void clearAudio (unsigned int offset, unsigned int length); + // Read data from internal 'input' audio buffer to an external audio buffer. + // (*only* works if WRITE_AUDIO_INPUT_TO_BUFFER is enabled). + static void readAudioInput (unsigned int offset, unsigned int length, float *left, float *right); + /** * Set the audio input gain. (multiplier applied to mic input) */ @@ -69,7 +91,7 @@ private: */ struct BufferFrame{ float l, r; - } *buffer; + } *buffer, *inputBuffer; /** * Length of the audio buffer. */ @@ -88,14 +110,20 @@ private: AudioData () : bufferPos(0) { inputGain = 1.0f; buffer = new BufferFrame[bufferLength]; - for (unsigned int i = 0; i < bufferLength; ++i) { - buffer[i].l = buffer[i].r = 0; - } + memset((float*)buffer, 0, sizeof(float) * bufferLength * 2); + #if WRITE_AUDIO_INPUT_TO_BUFFER + inputBuffer = new BufferFrame[bufferLength]; + memset((float*)inputBuffer, 0, sizeof(float) * bufferLength * 2); + #else + inputBuffer = NULL; + #endif } ~AudioData () { delete[] buffer; + #if WRITE_AUDIO_INPUT_TO_BUFFER + delete[] inputBuffer; + #endif } - }*data; /** * Internal audio stream handle. diff --git a/interface.xcodeproj/project.pbxproj b/interface.xcodeproj/project.pbxproj index 0a0a767709..8380081120 100644 --- a/interface.xcodeproj/project.pbxproj +++ b/interface.xcodeproj/project.pbxproj @@ -216,6 +216,10 @@ "\"$(SRCROOT)\"", /usr/local/lib, ); + OTHER_CPLUSPLUSFLAGS = ( + "-O3", + "$(OTHER_CFLAGS)", + ); PRODUCT_NAME = interface; }; name = Debug; @@ -233,6 +237,10 @@ "\"$(SRCROOT)\"", /usr/local/lib, ); + OTHER_CPLUSPLUSFLAGS = ( + "-O3", + "$(OTHER_CFLAGS)", + ); PRODUCT_NAME = interface; }; name = Release; diff --git a/interface.xcodeproj/project.xcworkspace/xcuserdata/Seiji.xcuserdatad/UserInterfaceState.xcuserstate b/interface.xcodeproj/project.xcworkspace/xcuserdata/Seiji.xcuserdatad/UserInterfaceState.xcuserstate index ffea69364a3fb90c1b3bbc5db6276faaa35c8518..de265ecd95d91a842eaab269b0f930607119f430 100644 GIT binary patch literal 25873 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 literal 26817 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