2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2011-02-25 01:05:47 +03:00
|
|
|
// $Id$
|
2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2011-01-26 02:29:08 +03:00
|
|
|
// Copyright (C) 2001-2011 The Bochs Project
|
2001-04-10 05:04:59 +04:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
2009-02-08 12:05:52 +03:00
|
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2009-02-08 00:05:31 +03:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
// This file (SOUNDWIN.H) written and donated by Josef Drexler
|
|
|
|
|
|
|
|
#if defined(WIN32)
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
// uncomment one of the following two #defines
|
|
|
|
//#define usesndPlaySnd
|
|
|
|
#define usewaveOut
|
|
|
|
|
|
|
|
#define BX_SOUND_WINDOWS_MAXSYSEXLEN 256 // maximum supported length of a sysex message
|
|
|
|
|
2011-03-20 21:02:12 +03:00
|
|
|
#define BX_SOUND_WINDOWS_NBUF 64 // number of buffers for the output, must be power of 2 and >= 4
|
|
|
|
#define BX_SOUND_WINDOWS_NMASK (BX_SOUND_WINDOWS_NBUF - 1)
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
#ifndef WAVEMAPPER
|
2011-03-20 21:02:12 +03:00
|
|
|
#define WAVEMAPPER -1
|
2001-04-10 05:04:59 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Definitions for WINMM.DLL, if not defined already
|
|
|
|
#ifndef MMSYSERR_NOERROR
|
|
|
|
|
|
|
|
#pragma pack(1)
|
|
|
|
|
|
|
|
typedef UINT HMIDIOUT;
|
|
|
|
typedef HMIDIOUT *LPHMIDIOUT;
|
|
|
|
typedef struct midihdr_tag {
|
|
|
|
LPSTR lpData;
|
|
|
|
DWORD dwBufferLength;
|
|
|
|
DWORD dwBytesRecorded;
|
|
|
|
DWORD dwUser;
|
|
|
|
DWORD dwFlags;
|
|
|
|
struct midihdr_tag *lpNext;
|
|
|
|
DWORD reserved;
|
|
|
|
} MIDIHDR, *LPMIDIHDR;
|
|
|
|
|
|
|
|
typedef UINT HWAVEOUT;
|
|
|
|
typedef HWAVEOUT *LPHWAVEOUT;
|
|
|
|
|
|
|
|
typedef struct wavehdr_tag {
|
|
|
|
LPSTR lpData;
|
|
|
|
DWORD dwBufferLength;
|
|
|
|
DWORD dwBytesRecorded;
|
|
|
|
DWORD dwUser;
|
|
|
|
DWORD dwFlags;
|
|
|
|
DWORD dwLoops;
|
|
|
|
struct wavehdr_tag *lpNext;
|
|
|
|
DWORD reserved;
|
|
|
|
} WAVEHDR, *LPWAVEHDR;
|
|
|
|
|
|
|
|
#define WHDR_DONE 0x00000001
|
|
|
|
#define WHDR_PREPARED 0x00000002
|
|
|
|
#define WHDR_BEGINLOOP 0x00000004
|
|
|
|
#define WHDR_ENDLOOP 0x00000008
|
|
|
|
#define WHDR_INQUEUE 0x00000010
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct waveformat_tag {
|
|
|
|
WORD wFormatTag;
|
|
|
|
WORD nChannels;
|
|
|
|
DWORD nSamplesPerSec;
|
|
|
|
DWORD nAvgBytesPerSec;
|
|
|
|
WORD nBlockAlign;
|
|
|
|
} WAVEFORMAT, *LPWAVEFORMAT;
|
|
|
|
|
|
|
|
#define WAVE_FORMAT_PCM 1
|
|
|
|
|
|
|
|
typedef struct pcmwaveformat_tag {
|
|
|
|
WAVEFORMAT wf;
|
|
|
|
WORD wBitsPerSample;
|
|
|
|
} PCMWAVEFORMAT, *LPPCMWAVEFORMAT;
|
|
|
|
|
|
|
|
#define MIDIMAPPER -1
|
|
|
|
|
|
|
|
#define CALLBACK_NULL 0x00000000
|
|
|
|
#define CALLBACK_WINDOW 0x00010000
|
|
|
|
#define CALLBACK_TASK 0x00020000
|
|
|
|
#define CALLBACK_FUNCTION 0x00030000
|
|
|
|
|
|
|
|
#define MMSYSERR_NOERROR 0
|
|
|
|
#define MMSYSERR_ERROR 1
|
|
|
|
#define MMSYSERR_BADDEVICEID 2
|
|
|
|
#define MMSYSERR_NOTENABLED 3
|
|
|
|
#define MMSYSERR_ALLOCATED 4
|
|
|
|
#define MMSYSERR_INVALHANDLE 5
|
|
|
|
#define MMSYSERR_NODRIVER 6
|
|
|
|
#define MMSYSERR_NOMEM 7
|
|
|
|
#define MMSYSERR_NOTSUPPORTED 8
|
|
|
|
#define MMSYSERR_NOMAP 7
|
|
|
|
|
|
|
|
#define MIDIERR_UNPREPARED 64
|
|
|
|
#define MIDIERR_STILLPLAYING 65
|
|
|
|
#define MIDIERR_NOTREADY 66
|
|
|
|
#define MIDIERR_NODEVICE 67
|
|
|
|
|
|
|
|
#define WAVERR_BADFORMAT 32
|
|
|
|
#define WAVERR_STILLPLAYING 33
|
|
|
|
#define WAVERR_UNPREPARED 34
|
|
|
|
#define WAVERR_SYNC 35
|
|
|
|
|
|
|
|
#define MAXERRORLENGTH 128
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
UINT STDCALL midiOutOpen(LPHMIDIOUT, UINT, DWORD, DWORD, DWORD);
|
|
|
|
UINT STDCALL midiOutShortMsg(HMIDIOUT, DWORD);
|
|
|
|
UINT STDCALL midiOutLongMsg(HMIDIOUT, LPMIDIHDR, UINT);
|
|
|
|
UINT STDCALL midiOutPrepareHeader(HMIDIOUT, LPMIDIHDR, UINT);
|
|
|
|
UINT STDCALL midiOutUnprepareHeader(HMIDIOUT, LPMIDIHDR, UINT);
|
|
|
|
UINT STDCALL midiOutReset(HMIDIOUT);
|
|
|
|
UINT STDCALL midiOutClose(HMIDIOUT);
|
|
|
|
|
|
|
|
UINT STDCALL waveOutOpen(LPHWAVEOUT, UINT, LPWAVEFORMAT, DWORD, DWORD, DWORD);
|
|
|
|
UINT STDCALL waveOutWrite(HWAVEOUT, LPWAVEHDR, UINT);
|
|
|
|
UINT STDCALL waveOutPrepareHeader(HWAVEOUT, LPWAVEHDR, UINT);
|
|
|
|
UINT STDCALL waveOutUnprepareHeader(HWAVEOUT, LPWAVEHDR, UINT);
|
|
|
|
UINT STDCALL waveOutReset(HWAVEOUT);
|
|
|
|
UINT STDCALL waveOutClose(HWAVEOUT);
|
|
|
|
|
|
|
|
UINT STDCALL waveOutGetErrorTextA(UINT, LPSTR, UINT);
|
|
|
|
|
|
|
|
BOOL STDCALL sndPlaySoundA(LPCSTR, UINT);
|
|
|
|
}
|
2006-02-05 20:13:54 +03:00
|
|
|
#pragma pack(0)
|
|
|
|
|
|
|
|
#endif // MMSYSERR_NOERROR defined
|
|
|
|
|
|
|
|
#ifndef WAVEFILEHEADER
|
|
|
|
|
|
|
|
#pragma pack(push, 1)
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char RIFF[4];
|
|
|
|
Bit32u length;
|
|
|
|
char TYPE[4];
|
|
|
|
char chnk[4];
|
|
|
|
Bit32u chnklen;
|
|
|
|
PCMWAVEFORMAT waveformat;
|
|
|
|
char chnk2[4];
|
|
|
|
Bit32u chnk2len;
|
|
|
|
char data[1];
|
|
|
|
} WAVEFILEHEADER, *LPWAVEFILEHEADER;
|
2006-02-05 20:13:54 +03:00
|
|
|
#pragma pack(pop)
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2006-02-05 20:13:54 +03:00
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2011-03-19 15:57:13 +03:00
|
|
|
class bx_sound_windows_c : public bx_sound_lowlevel_c {
|
2001-04-10 05:04:59 +04:00
|
|
|
public:
|
2011-02-11 01:58:22 +03:00
|
|
|
bx_sound_windows_c(logfunctions *dev);
|
2011-01-26 02:29:08 +03:00
|
|
|
virtual ~bx_sound_windows_c();
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2012-06-09 00:49:39 +04:00
|
|
|
virtual int get_type() {return BX_SOUNDLOW_WIN;}
|
|
|
|
|
2011-01-26 02:29:08 +03:00
|
|
|
virtual int waveready();
|
|
|
|
virtual int midiready();
|
|
|
|
|
2011-02-13 20:26:52 +03:00
|
|
|
virtual int openmidioutput(const char *mididev);
|
2011-01-26 02:29:08 +03:00
|
|
|
virtual int sendmidicommand(int delta, int command, int length, Bit8u data[]);
|
|
|
|
virtual int closemidioutput();
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2011-02-13 20:26:52 +03:00
|
|
|
virtual int openwaveoutput(const char *wavedev);
|
2011-03-20 21:02:12 +03:00
|
|
|
virtual int startwaveplayback(int frequency, int bits, bx_bool stereo, int format);
|
2011-01-26 02:29:08 +03:00
|
|
|
virtual int sendwavepacket(int length, Bit8u data[]);
|
|
|
|
virtual int stopwaveplayback();
|
|
|
|
virtual int closewaveoutput();
|
|
|
|
|
2011-05-14 01:08:33 +04:00
|
|
|
virtual int openwaveinput(const char *wavedev, sound_record_handler_t rh);
|
|
|
|
virtual int startwaverecord(int frequency, int bits, bx_bool stereo, int format);
|
|
|
|
virtual int getwavepacket(int length, Bit8u data[]);
|
|
|
|
virtual int stopwaverecord();
|
|
|
|
virtual int closewaveinput();
|
|
|
|
|
|
|
|
static void record_timer_handler(void *);
|
|
|
|
void record_timer(void);
|
|
|
|
|
2011-01-26 02:29:08 +03:00
|
|
|
private:
|
2011-03-19 15:57:13 +03:00
|
|
|
struct bx_sound_waveinfo_struct {
|
2001-04-10 05:04:59 +04:00
|
|
|
int frequency;
|
|
|
|
int bits;
|
2011-03-20 21:02:12 +03:00
|
|
|
bx_bool stereo;
|
2001-04-10 05:04:59 +04:00
|
|
|
int format;
|
|
|
|
};
|
|
|
|
|
|
|
|
HMIDIOUT MidiOut; // Midi output device
|
|
|
|
int MidiOpen; // is it open?
|
2011-05-14 01:08:33 +04:00
|
|
|
HWAVEOUT hWaveOut; // Wave output device
|
|
|
|
int WaveOutOpen; // is it open?
|
|
|
|
HWAVEIN hWaveIn; // Wave input device
|
|
|
|
int WaveInOpen; // is it open?
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
UINT WaveDevice; // Wave device ID, for waveOutOpen
|
|
|
|
|
2011-03-19 15:57:13 +03:00
|
|
|
// some data for the wave buffers
|
2001-04-10 05:04:59 +04:00
|
|
|
HANDLE DataHandle; // returned by GlobalAlloc()
|
|
|
|
Bit8u *DataPointer; // returned by GlobalLock()
|
|
|
|
|
|
|
|
LPWAVEHDR WaveHeader[BX_SOUND_WINDOWS_NBUF];
|
|
|
|
LPSTR WaveData[BX_SOUND_WINDOWS_NBUF];
|
2011-05-14 01:08:33 +04:00
|
|
|
LPWAVEHDR WaveInHdr;
|
|
|
|
LPSTR WaveInData;
|
|
|
|
bx_bool recording;
|
2001-04-10 05:04:59 +04:00
|
|
|
int length[BX_SOUND_WINDOWS_NBUF]; // length of the data in the buffer
|
|
|
|
int needreopen; // if the format has changed
|
|
|
|
int head,tailfull,tailplay; // These are for three states of the buffers: empty, full, played
|
2011-05-14 01:08:33 +04:00
|
|
|
bx_sound_waveinfo_struct WaveInfo[2]; // format for the next buffer to be played
|
2001-04-10 05:04:59 +04:00
|
|
|
int iswaveready;
|
|
|
|
|
2011-03-19 15:57:13 +03:00
|
|
|
// and the midi buffer for the SYSEX messages
|
2001-04-10 05:04:59 +04:00
|
|
|
LPMIDIHDR MidiHeader;
|
|
|
|
LPSTR MidiData;
|
|
|
|
int ismidiready;
|
|
|
|
|
|
|
|
int playnextbuffer();
|
2011-05-14 01:08:33 +04:00
|
|
|
int recordnextpacket();
|
2001-04-10 05:04:59 +04:00
|
|
|
void checkmidiready();
|
|
|
|
void checkwaveready();
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // defined(WIN32)
|