Implemented adaptive HAL driver. Somewhat sensitive to machine load. Working on feeder-thread implementation to aleviate sensitivity.

This commit is contained in:
Charlie Reading
2004-02-20 16:37:07 +00:00
parent 21c44056f2
commit c6e410dbe3
2 changed files with 776 additions and 303 deletions
File diff suppressed because it is too large Load Diff
+87 -45
View File
@@ -4,79 +4,121 @@
* RageSoundDriver_CA.h * RageSoundDriver_CA.h
* stepmania * stepmania
* *
* Created by Steve Checkoway on Tue Aug 26 2003. * Sound stream pool code based on RageSoundDriver_ALSA9.h/.cpp by Glen Maynard.
* Copyright (c) 2003 Steve Checkoway. All rights reserved. *
* Copyright (c) 2003 by the person(s) listed below. All rights reserved.
* Steve Checkoway
* Charlie Reading
* *
*/ */
#include "RageSoundDriver.h" #include "RageSoundDriver.h"
#define BROKEN_DRIVER_1 1 #include "RageThreads.h"
#define BROKEN_DRIVER_2 2
#define DRIVER_UNFINISHED 0
#define DRIVER_HAL 1
#define DRIVER DRIVER_HAL
#define FEEDER_DIRECT 0
#define FEEDER_THREAD 1
#define FEEDER FEEDER_DIRECT
#define RESYNC_NEVER 0
#define RESYNC_INSTANTANEOUS 1
#define RESYNC_ACCUMULATE 2
#define RESYNC RESYNC_ACCUMULATE
#define CURRENT_DRIVER BROKEN_DRIVER_2
struct AudioTimeStamp; struct AudioTimeStamp;
struct AudioBufferList; struct AudioBufferList;
#if CURRENT_DRIVER == BROKEN_DRIVER_1 typedef unsigned char Boolean;
struct OpaqueAudioConverter;
typedef struct OpaqueAudioConverter *AudioConverterRef;
#endif
typedef long OSStatus; typedef long OSStatus;
typedef unsigned long UInt32; typedef unsigned long UInt32;
typedef UInt32 AudioDeviceID; typedef UInt32 AudioDeviceID;
typedef UInt32 AudioDevicePropertyID;
typedef UInt32 AudioUnitRenderActionFlags; typedef UInt32 AudioUnitRenderActionFlags;
#if CURRENT_DRIVER == BROKEN_DRIVER_2 typedef double Float64;
struct ComponentInstanceRecord; struct OpaqueAudioConverter;
typedef struct ComponentInstanceRecord *AudioUnit; typedef struct OpaqueAudioConverter *AudioConverterRef;
struct AudioStreamBasicDescription;
#if (FEEDER == FEEDER_THREAD)
class VirtualRingBuffer;
#endif #endif
class RageSound_CA: public RageSoundDriver class RageSound_CA: public RageSoundDriver
{ {
private: private:
typedef struct sound { /* Sound stream */
RageSoundBase *snd; struct stream
bool stopping; {
enum { INACTIVE, PLAYING, STOPPING } state;
RageSound *snd;
int flush_pos; int flush_pos;
sound() { snd=NULL; stopping=false; flush_pos=0; }
} *soundPtr;
vector<soundPtr> sounds; void clear() { snd=NULL; state=INACTIVE; flush_pos=0; }
#if CURRENT_DRIVER == BROKEN_DRIVER_1 stream() { clear(); }
AudioConverterRef converter;
#elif CURRENT_DRIVER == BROKEN_DRIVER_2 };
AudioUnit outputUnit; friend struct stream;
#endif
/* Pool of available streams. */
vector<stream *> stream_pool;
int streamsInUse;
AudioDeviceID outputDevice; AudioDeviceID outputDevice;
float latency; AudioStreamBasicDescription *idealFormat;
AudioStreamBasicDescription *actualFormat;
UInt32 buffersize; UInt32 buffersize;
int samplesPerBuffer;
AudioConverterRef converter;
bool shutdown;
float latency;
Float64 startSampleTime;
int expected;
#if (RESYNC != RESYNC_NEVER)
int packetsOff;
int packetsOffSamples;
#endif
#if (FEEDER == FEEDER_THREAD)
size_t vrbChunkSize;
VirtualRingBuffer *vrb;
RageThread feederThread;
int nextSampleToWrite;
static int FeederThread_start(void *p);
void FeederThread();
#endif
int ConvertSampleTimeToPosition(const Float64 sampleTime) const;
int ConvertAudioTimeStampToPosition(const AudioTimeStamp *time) const;
static int ConvertAudioTimeStampToPosition(const AudioTimeStamp *time);
protected: protected:
virtual void StartMixing(RageSoundBase *snd); virtual void StartMixing(RageSound *snd);
virtual void StopMixing(RageSoundBase *snd);
virtual int GetPosition(const RageSoundBase *snd) const;
virtual void Update (float delta); virtual void Update (float delta);
virtual float GetPlayLatency() const { return latency; } virtual void StopMixing(RageSound *snd);
virtual int GetPosition(const RageSound *snd) const;
virtual float GetPlayLatency() const;
virtual int GetSampleRate() const;
size_t smSamplesToBytes(int samples);
int smBytesToSamples(size_t bytes);
size_t caSamplesToBytes(int samples);
int caBytesToSamples(size_t bytes);
public: public:
RageSound_CA(); RageSound_CA();
virtual ~RageSound_CA(); virtual ~RageSound_CA();
#if CURRENT_DRIVER == BROKEN_DRIVER_1
static OSStatus GetData(AudioDeviceID inDevice, virtual size_t FillSoundBuffer(char* buffer, size_t maxBufferSize, int position);
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData, static OSStatus GetData(AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData);
const AudioTimeStamp* inInputTime, static OSStatus OverloadListener(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData);
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData);
#elif CURRENT_DRIVER == BROKEN_DRIVER_2
static OSStatus GetData(void *inRecCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumFrames,
AudioBufferList *ioData);
#endif
}; };
#endif RAGE_SOUND_CA #endif RAGE_SOUND_CA