oolite/OOAlsaSound.h
Dylan Smith 44521c251f more sound debugging
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@28 127b21dd-08f5-0310-b4b7-95ae10353056
2005-04-28 20:15:20 +00:00

117 lines
2.9 KiB
Objective-C

//
// OOALSASound.h: Interface for oolite to the Advanced Linux Sound
// Achitecture.
// Implements methods from NSSound which are used by oolite.
//
// It is a bit of a stopgap measure since the base NSSound is fine,
// well, except the gnustep_sndd (sound daemon) crashes each time
// it plays a sound, and it probably uses OSS instead of ALSA.
// We also don't want a dependency on gnustep_sndd for statically-linked
// versions of oolite.
//
// Dylan Smith, 2005-04-22
//
#import <AppKit/NSSound.h>
#import <Foundation/NSLock.h>
#include <alsa/asoundlib.h>
#include <semaphore.h>
@interface OOSound : NSSound
{
BOOL isPlaying;
}
- (BOOL) pause;
- (BOOL) isPlaying;
- (BOOL) play;
- (BOOL) stop;
- (BOOL) resume;
// we only do 44.1kHz so resample anything that's not. This makes
// the mixer much simpler. TODO: make the mixer better.
- (void) resample;
// accessor methods. Only OOAlsaSoundThread should be calling these.
- (NSData *)getData;
- (float)getBYTERate;
- (float)getFrameSize;
- (long)getDataSize;
- (long)getFrameCount;
- (int)getChannelCount;
- (const unsigned char *)getBufferEnd;
// call startup when starting to play a sound, and resetState when
// finishing. The two methods set the pointers right to do stuff.
- (void)resetState;
- (void)startup;
@end
// Some constants. (We normalize anything sent to us to these values)
#define PERIODS 2
#define PERIODSIZE 8192
#define MIXBUFSIZE 2048
#define SAMPLERATE 44100
#define CHANNELS 2
#define MAXTRACKS 6
#define FRAMESIZE 4
// Instances of this class control a per-PCM thread that is responsible
// for controlling access to the hardware.
typedef unsigned long Frame;
typedef short Sample;
#ifndef BYTE
typedef unsigned char BYTE;
#endif
typedef struct _soundChunk
{
Frame *buf;
Frame *bufEnd;
} SoundChunk;
@interface OOAlsaSoundThread : NSObject
{
snd_pcm_t *pcm_handle;
snd_pcm_hw_params_t *hwparams;
unsigned long bufsz;
// controlling semapore
sem_t soundSem;
// sounds to play
OOSound *track[MAXTRACKS];
SoundChunk trackBuffer[MAXTRACKS];
Frame *chunkBuf;
}
// init creates the thread and returns self.
- (id) init;
// soundThread is a single thread per ALSA PCM device. It should only
// ever be called once per PCM device.
- (void) soundThread: (id)obj;
- (void) stopTrack: (OOSound *)trackToStop;
// playBuffer sets up the buffer to be played and posts the semaphore
// to crank it up.
- (void) playBuffer: (OOSound *)sound;
// initAlsa sets up the device.
- (BOOL) initAlsa;
// Quite a lot of nasty stuff is done here. The implementation almost
// certainly can be improved, but I think it'll take reading the
// ALSA library code to figure out a better way to do this.
// If you think this code is bizarre or at best baroque I quite agree!
- (BOOL)mixChunks;
@end
static OOAlsaSoundThread *soundThread;
// a bet to self: this class is still in use 2 years from now...