overte-thingvellir/audio.h

151 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// audio.h
// interface
//
// Created by Seiji Emery on 9/2/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#ifndef interface_audio_h
#define interface_audio_h
#include "portaudio.h"
// 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.
*
* Contains static methods that write to an internal audio buffer, which
is read from by a portaudio callback.
* Responsible for initializing and terminating portaudio. Audio::init()
and Audio::terminate() should be called at the beginning and end of
program execution.
*/
class Audio {
public:
// Initializes portaudio. Should be called at the beginning of program execution.
static bool init ();
// Deinitializes portaudio. Should be called at the end of program execution.
static bool terminate ();
// Write methods: write to internal audio buffer.
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)
*/
static void setInputGain (float gain) {
data->inputGain = gain;
}
/**
* Get the internal portaudio error code (paNoError if none).
* Use in conjunction with Audio::init() or Audio::terminate(), as it is not
impacted by any other methods.
*/
const PaError getError () { return err; }
private:
/**
* Set to true by Audio::init() and false by Audio::terminate().
* Used to prevent Audio::terminate() from deleting uninitialized memory.
*/
static bool initialized;
/**
* Internal audio data.
* Used to communicate with the audio callback code via a shared pointer.
*/
static struct AudioData {
/**
* Internal (stereo) audio buffer.
* Written to by Audio I/O methods and the audio callback.
* As this is a ring buffer, it should not be written to directly thus methods
like Audio::writeAudio are provided.
*/
struct BufferFrame{
float l, r;
} *buffer, *inputBuffer;
/**
* Length of the audio buffer.
*/
const static unsigned int bufferLength = 1000;
/**
* Current position (start) within the ring buffer.
* Updated by the audio callback.
*/
unsigned int bufferPos;
/**
* Audio input gain (multiplier applied to the incoming audio stream).
* Use Audio::setInputGain() to modify this.
*/
static float inputGain;// = 1.f;
AudioData () : bufferPos(0) {
inputGain = 1.0f;
buffer = new BufferFrame[bufferLength];
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.
*/
static PaStream *stream;
/**
* Internal error code (used only by Audio::init() and Audio::terminate()).
*/
static PaError err;
Audio (); // prevent instantiation (private constructor)
friend int audioCallback (const void*, void*, unsigned long, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void*);
};
// Audio callback called by portaudio.
int audioCallback (const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData);
#endif