AudioIO.h
#ifndef __AUDACITY_AUDIO_IO__
#define __AUDACITY_AUDIO_IO__
#include "portaudio.h"
#include "Audacity.h"
#if USE_PORTMIXER
#include "portmixer.h"
#endif
#include <wx/string.h>
#include <wx/thread.h>
#include "WaveTrack.h"
#include "SampleFormat.h"
class AudioIO;
class RingBuffer;
class Mixer;
class Resample;
class TimeTrack;
class AudioThread;
class Meter;
extern AudioIO *gAudioIO;
void InitAudioIO();
void DeinitAudioIO();
wxString DeviceName(const PaDeviceInfo* info);
class AudioIOListener {
public:
AudioIOListener() {}
virtual ~AudioIOListener() {}
virtual void OnAudioIORate(int rate) = 0;
virtual void OnAudioIOStartRecording() = 0;
virtual void OnAudioIOStopRecording() = 0;
virtual void OnAudioIONewBlockFiles(const wxString& blockFileLog) = 0;
};
00055 class AudioIO {
public:
AudioIO();
~AudioIO();
void StartMonitoring(double sampleRate);
int StartStream(WaveTrackArray playbackTracks, WaveTrackArray captureTracks,
TimeTrack *timeTrack, double sampleRate,
double t0, double t1,
AudioIOListener* listener,
bool playLooped = false,
double cutPreviewGapStart = 0.0,
double cutPreviewGapLen = 0.0);
void StopStream();
void SeekStream(double seconds) { mSeek = seconds; };
bool IsBusy();
bool IsStreamActive();
bool IsStreamActive(int token);
bool IsAudioTokenActive(int token);
bool IsMonitoring();
void SetPaused(bool state);
bool IsPaused();
void SetMixer(int inputSource, float inputVolume,
float playbackVolume);
void GetMixer(int *inputSource, float *inputVolume,
float *playbackVolume);
wxArrayString GetInputSourceNames();
void HandleDeviceChange();
void SetMeters(Meter *inputMeter, Meter *outputMeter);
static wxArrayLong GetSupportedPlaybackRates(wxString devName = wxT(""),
double rate = 0.0);
static wxArrayLong GetSupportedCaptureRates(wxString devName = wxT(""),
double rate = 0.0);
static wxArrayLong GetSupportedSampleRates(wxString playDevice = wxT(""),
wxString recDevice = wxT(""),
double rate = 0.0);
static int GetOptimalSupportedSampleRate();
double GetStreamTime();
sampleFormat GetCaptureFormat() { return mCaptureFormat; }
int GetNumCaptureChannels() { return mNumCaptureChannels; }
static const int StandardRates[];
static const int NumStandardRates;
private:
long GetBestRate(bool capturing, double sampleRate);
bool StartPortAudioStream(double sampleRate,
unsigned int numPlaybackChannels,
unsigned int numCaptureChannels,
sampleFormat captureFormat);
void FillBuffers();
int GetCommonlyAvailPlayback();
int GetCommonlyAvailCapture();
double NormalizeStreamTime(double absoluteTime) const;
AudioThread *mThread;
Resample **mResample;
RingBuffer **mCaptureBuffers;
WaveTrackArray mCaptureTracks;
RingBuffer **mPlaybackBuffers;
WaveTrackArray mPlaybackTracks;
Mixer **mPlaybackMixers;
int mStreamToken;
int mStopStreamCount;
static int mNextStreamToken;
double mFactor;
double mRate;
double mT;
double mT0;
double mT1;
double mTime;
double mWarpedT1;
double mSeek;
double mPlaySpeed;
double mPlaybackRingBufferSecs;
double mCaptureRingBufferSecs;
double mMaxPlaybackSecsToCopy;
double mMinCaptureSecsToCopy;
bool mPaused;
#if USE_PORTAUDIO_V19
PaStream *mPortStreamV19;
#else
PortAudioStream *mPortStreamV18;
volatile bool mInCallbackFinishedState;
#endif
bool mSoftwarePlaythrough;
unsigned int mNumCaptureChannels;
unsigned int mNumPlaybackChannels;
sampleFormat mCaptureFormat;
float *mTempFloats;
int mLostSamples;
volatile bool mAudioThreadShouldCallFillBuffersOnce;
volatile bool mAudioThreadFillBuffersLoopRunning;
volatile bool mAudioThreadFillBuffersLoopActive;
volatile double mLastRecordingOffset;
PaError mLastPaError;
Meter *mInputMeter;
Meter *mOutputMeter;
bool mUpdateMeters;
bool mUpdatingMeters;
#if USE_PORTMIXER
PxMixer *mPortMixer;
float mPreviousHWPlaythrough;
#endif
bool mEmulateMixerOutputVol;
bool mEmulateMixerInputVol;
float mMixerOutputVol;
float mMixerInputVol;
bool mPlayLooped;
double mCutPreviewGapStart;
double mCutPreviewGapLen;
AudioIOListener* mListener;
friend class AudioThread;
friend void InitAudioIO();
friend void DeinitAudioIO();
#if USE_PORTAUDIO_V19
friend int audacityAudioCallback(
const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData );
#else
friend int audacityAudioCallback(
void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
PaTimestamp outTime, void *userData );
#endif
};
#endif