apple2ix/src/audio/soundcore.h

124 lines
4.2 KiB
C
Raw Normal View History

/*
* Apple // emulator for *nix
*
* This software package is subject to the GNU General Public License
* version 2 or later (your choice) as published by the Free Software
* Foundation.
*
* THERE ARE NO WARRANTIES WHATSOEVER.
*
*/
/*
* Apple //e core sound system support. Source inspired/derived from AppleWin.
*
*/
#ifndef _SOUNDCORE_H_
#define _SOUNDCORE_H_
#define MAX_SAMPLES (8*1024)
#define AUDIO_STATUS_PLAYING 0x00000001
#define AUDIO_STATUS_NOTPLAYING 0x08000000
2015-06-13 20:23:49 +00:00
typedef struct IDirectSoundBuffer {
void *_this;
int (*SetVolume)(void* _this, long lVolume);
int (*GetVolume)(void* _this, long *lplVolume);
int (*GetCurrentPosition)(void* _this, unsigned long *lpdwCurrentPlayCursor, unsigned long *lpdwCurrentWriteCursor);
int (*Stop)(void* _this);
// This method restores the memory allocation for a lost sound buffer for the specified DirectSoundBuffer object.
int (*Restore)(void *_this);
int (*Play)(void* _this, unsigned long dwReserved1, unsigned long dwReserved2, unsigned long dwFlags);
// This method obtains a valid write pointer to the sound buffer's audio data
int (*Lock)(void* _this, unsigned long dwWriteCursor, unsigned long dwWriteBytes, void **lplpvAudioPtr1, unsigned long *lpdwAudioBytes1, void **lplpvAudioPtr2, unsigned long *lpdwAudioBytes2, unsigned long dwFlags);
// This method releases a locked sound buffer.
int (*Unlock)(void* _this, void *lpvAudioPtr1, unsigned long dwAudioBytes1, void *lpvAudioPtr2, unsigned long dwAudioBytes2);
int (*GetStatus)(void* _this, unsigned long *lpdwStatus);
// Mockingboard-specific HACKS
2015-06-13 20:23:49 +00:00
int (*UnlockStaticBuffer)(void* _this, unsigned long dwAudioBytes);
int (*Replay)(void* _this);
} IDirectSoundBuffer, *LPDIRECTSOUNDBUFFER, **LPLPDIRECTSOUNDBUFFER;
typedef struct AudioParams_s {
uint16_t nChannels;
unsigned long nSamplesPerSec;
unsigned long nAvgBytesPerSec;
uint16_t nBlockAlign;
uint16_t wBitsPerSample;
unsigned long dwBufferBytes;
} AudioParams_s;
typedef struct IDirectSound {
void *implementation_specific;
int (*CreateSoundBuffer)(AudioParams_s *pcDSBufferDesc, LPDIRECTSOUNDBUFFER * ppDSBuffer, void *pUnkOuter);
int (*DestroySoundBuffer)(LPDIRECTSOUNDBUFFER * ppDSBuffer);
} IDirectSound, *LPDIRECTSOUND;
typedef struct IDirectSound SoundSystemStruct;
typedef struct
{
Refactor speaker system to prevent audio glitches and to support CPU automatic speed switching Squashed commit of the following: REFACTOR : fix comments, logging, and rename some variables REFACTOR : fix up some commentary, clean deadc0de REFACTOR : mostly fix all the audio glitches - amplitudes of samples are gradually shifted to zero when speaker has fallen silent - simplifies speaker state machine - fullspeed mode only enqueues quiet samples REFACTOR : fix up a number of other functions and comments REFACTOR : clean up code to submit normal speed wave buffer to OpenAL Move some initializations to the cpu_thread() REFACTOR : properly reset the speaker cycles access counter so we don't underflow and assert REFACTOR : should never get a split buffer from our soundcore implementation Fix warning from gcc ... static array size needs to be computed from integer values REFACTOR : gcc (but not clang) complains about these, so just make them preprocessor defines REFACTOR : use unsigned long long because we don't actually care that this counter is 64bit REFACTOR : remainder_buffer and miscellaneous tweaks - Adds implementation commentary to document remainder_buffer purpose - Also adds sample average for square wave boundary in case where remainder_buffer not used (whole-sample boundary) - Variable renaming and code shuffling REFACTOR : do not dynamically alloc remainder buffer - Never attribute to cache-coherancy bugs what is a simple thread race =P REFACTOR : comments and whitespace REFACTOR : rename public speaker API functions REFACTOR : clean up public speaker API REFACTOR : tabs to spaces REFACTOR : moar deadc0de clean up and renaming REFACTOR : remove deadc0de paths from soundcore REFACTOR : fully excise soundtype stuff now that we only support soundcard output Move a file static to function scope REFACTOR : rename more variables and remove deadc0de REFACTOR : samples_buffer naming and change to explict int16_t REFACTOR : removed deadc0de and shuffled code locations REFACTOR : remainder buffer naming and clarify type REFACTOR : move joystick timing to VM module and remove header visibility REFACTOR : clarify speaker variable name REFACTOR : clarify cycle counting codepaths REFACTOR : VBL/timing interfaces - eliminates passing around a common global REFACTOR : names and comments HACK around volume issue REFACTOR : rename speaker feedback variable REFACTOR : rename global total cycle count REFACTOR : rename a constant Fix test builds REFACTOR: rename to is_fullspeed REFACTOR : local variable naming changes REFACTOR : migrate cycle timing variables to correct location and remove header visibility Allow fullspeed codepath to update speaker REFACTOR : remove deadc0de paths in prep for cleanup REFACTOR : speaker now manages its own VM entry point
2015-01-31 21:57:10 +00:00
LPDIRECTSOUNDBUFFER lpDSBvoice;
bool bActive; // Playback is active
bool bMute;
2015-06-07 18:50:45 +00:00
long nVolume; // Current volume (as used by DirectSound)
long nFadeVolume; // Current fade volume (as used by DirectSound)
2015-06-07 18:47:57 +00:00
unsigned long dwUserVolume; // Volume from slider on Property Sheet (0=Max)
Refactor speaker system to prevent audio glitches and to support CPU automatic speed switching Squashed commit of the following: REFACTOR : fix comments, logging, and rename some variables REFACTOR : fix up some commentary, clean deadc0de REFACTOR : mostly fix all the audio glitches - amplitudes of samples are gradually shifted to zero when speaker has fallen silent - simplifies speaker state machine - fullspeed mode only enqueues quiet samples REFACTOR : fix up a number of other functions and comments REFACTOR : clean up code to submit normal speed wave buffer to OpenAL Move some initializations to the cpu_thread() REFACTOR : properly reset the speaker cycles access counter so we don't underflow and assert REFACTOR : should never get a split buffer from our soundcore implementation Fix warning from gcc ... static array size needs to be computed from integer values REFACTOR : gcc (but not clang) complains about these, so just make them preprocessor defines REFACTOR : use unsigned long long because we don't actually care that this counter is 64bit REFACTOR : remainder_buffer and miscellaneous tweaks - Adds implementation commentary to document remainder_buffer purpose - Also adds sample average for square wave boundary in case where remainder_buffer not used (whole-sample boundary) - Variable renaming and code shuffling REFACTOR : do not dynamically alloc remainder buffer - Never attribute to cache-coherancy bugs what is a simple thread race =P REFACTOR : comments and whitespace REFACTOR : rename public speaker API functions REFACTOR : clean up public speaker API REFACTOR : tabs to spaces REFACTOR : moar deadc0de clean up and renaming REFACTOR : remove deadc0de paths from soundcore REFACTOR : fully excise soundtype stuff now that we only support soundcard output Move a file static to function scope REFACTOR : rename more variables and remove deadc0de REFACTOR : samples_buffer naming and change to explict int16_t REFACTOR : removed deadc0de and shuffled code locations REFACTOR : remainder buffer naming and clarify type REFACTOR : move joystick timing to VM module and remove header visibility REFACTOR : clarify speaker variable name REFACTOR : clarify cycle counting codepaths REFACTOR : VBL/timing interfaces - eliminates passing around a common global REFACTOR : names and comments HACK around volume issue REFACTOR : rename speaker feedback variable REFACTOR : rename global total cycle count REFACTOR : rename a constant Fix test builds REFACTOR: rename to is_fullspeed REFACTOR : local variable naming changes REFACTOR : migrate cycle timing variables to correct location and remove header visibility Allow fullspeed codepath to update speaker REFACTOR : remove deadc0de paths in prep for cleanup REFACTOR : speaker now manages its own VM entry point
2015-01-31 21:57:10 +00:00
bool bIsSpeaker;
bool bRecentlyActive; // (Speaker only) false after 0.2s of speaker inactivity
} VOICE, *PVOICE;
2015-06-07 18:47:57 +00:00
bool DSGetLock(LPDIRECTSOUNDBUFFER pVoice, unsigned long dwOffset, unsigned long dwBytes,
int16_t** ppDSLockedBuffer0, unsigned long* pdwDSLockedBufferSize0,
int16_t** ppDSLockedBuffer1, unsigned long* pdwDSLockedBufferSize1);
2015-06-07 18:47:57 +00:00
int DSGetSoundBuffer(VOICE* pVoice, unsigned long dwFlags, unsigned long dwBufferSize, unsigned long nSampleRate, int nChannels);
void DSReleaseSoundBuffer(VOICE* pVoice);
2015-06-07 18:47:57 +00:00
bool DSZeroVoiceBuffer(PVOICE Voice, char* pszDevName, unsigned long dwBufferSize);
bool DSZeroVoiceWritableBuffer(PVOICE Voice, char* pszDevName, unsigned long dwBufferSize);
typedef enum eFADE {FADE_NONE, FADE_IN, FADE_OUT} eFADE;
void SoundCore_SetFade(eFADE FadeType);
int SoundCore_GetErrorInc();
void SoundCore_SetErrorInc(const int nErrorInc);
int SoundCore_GetErrorMax();
void SoundCore_SetErrorMax(const int nErrorMax);
bool DSInit();
void DSUninit();
extern bool audio_isAvailable;
typedef struct audio_backend_s {
// mandatory audio backend functions
long (*init)(const char *sound_device, SoundSystemStruct **sound_struct);
long (*shutdown)(SoundSystemStruct **sound_struct);
long (*pause)(void);
long (*resume)(void);
long (*enumerateDevices)(char ***sound_devices, const int maxcount);
} audio_backend_s;
/*
* The registered audio backend (renderer).
*/
extern audio_backend_s *audio_backend;
#endif /* whole file */