Mercurial > mplayer.hg
changeset 13017:5b9c594dc6e9
untested multichannel support
author | faust3 |
---|---|
date | Sat, 14 Aug 2004 10:03:26 +0000 |
parents | 61d0fd8411cc |
children | adb93ef6b07f |
files | libao2/ao_win32.c |
diffstat | 1 files changed, 74 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/libao2/ao_win32.c Fri Aug 13 17:12:45 2004 +0000 +++ b/libao2/ao_win32.c Sat Aug 14 10:03:26 2004 +0000 @@ -31,6 +31,50 @@ #include "osdep/timer.h" #define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 +#define WAVE_FORMAT_EXTENSIBLE 0xFFFE + +static const GUID KSDATAFORMAT_SUBTYPE_PCM = { + 0x1,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71} +}; + +typedef struct { + WAVEFORMATEX Format; + union { + WORD wValidBitsPerSample; + WORD wSamplesPerBlock; + WORD wReserved; + } Samples; + DWORD dwChannelMask; + GUID SubFormat; +} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; + +#define SPEAKER_FRONT_LEFT 0x1 +#define SPEAKER_FRONT_RIGHT 0x2 +#define SPEAKER_FRONT_CENTER 0x4 +#define SPEAKER_LOW_FREQUENCY 0x8 +#define SPEAKER_BACK_LEFT 0x10 +#define SPEAKER_BACK_RIGHT 0x20 +#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 +#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 +#define SPEAKER_BACK_CENTER 0x100 +#define SPEAKER_SIDE_LEFT 0x200 +#define SPEAKER_SIDE_RIGHT 0x400 +#define SPEAKER_TOP_CENTER 0x800 +#define SPEAKER_TOP_FRONT_LEFT 0x1000 +#define SPEAKER_TOP_FRONT_CENTER 0x2000 +#define SPEAKER_TOP_FRONT_RIGHT 0x4000 +#define SPEAKER_TOP_BACK_LEFT 0x8000 +#define SPEAKER_TOP_BACK_CENTER 0x10000 +#define SPEAKER_TOP_BACK_RIGHT 0x20000 + +static const int channel_mask[] = { + SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY, + SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY, + SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_CENTER | SPEAKER_LOW_FREQUENCY, + SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_LOW_FREQUENCY +}; + + #define SAMPLESIZE 1024 #define BUFFER_SIZE 4096 @@ -98,7 +142,7 @@ // return: 1=success 0=fail static int init(int rate,int channels,int format,int flags) { - WAVEFORMATEX wformat; + WAVEFORMATEXTENSIBLE wformat; DWORD totalBufferSize = (BUFFER_SIZE + sizeof(WAVEHDR)) * BUFFER_COUNT; MMRESULT result; unsigned char* buffer; @@ -121,41 +165,47 @@ mp_msg(MSGT_AO, MSGL_V,"ao_win32: Buffersize:%d\n",ao_data.buffersize); //fill waveformatex - ZeroMemory( &wformat, sizeof(WAVEFORMATEX)); - wformat.cbSize = 0; /* size of _extra_ info */ - wformat.nChannels = channels; - wformat.nSamplesPerSec = rate; + ZeroMemory( &wformat, sizeof(WAVEFORMATEXTENSIBLE)); + wformat.Format.cbSize = (channels>2)?sizeof(WAVEFORMATEXTENSIBLE):0; + wformat.Format.nChannels = channels; + wformat.Format.nSamplesPerSec = rate; if(format == AFMT_AC3) { - wformat.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF; - wformat.wBitsPerSample = 16; - wformat.nBlockAlign = 4; + wformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF; + wformat.Format.wBitsPerSample = 16; + wformat.Format.nBlockAlign = 4; } else { - wformat.wFormatTag = WAVE_FORMAT_PCM; - wformat.wBitsPerSample = audio_out_format_bits(format); - wformat.nBlockAlign = wformat.nChannels * (wformat.wBitsPerSample >> 3); - } - wformat.nAvgBytesPerSec = wformat.nSamplesPerSec * wformat.nBlockAlign; + wformat.Format.wFormatTag = (channels>2)?WAVE_FORMAT_EXTENSIBLE:WAVE_FORMAT_PCM; + wformat.Format.wBitsPerSample = audio_out_format_bits(format); + wformat.Format.nBlockAlign = wformat.Format.nChannels * (wformat.Format.wBitsPerSample >> 3); + } + if(channels>2) + { + wformat.dwChannelMask = channel_mask[channels-3]; + wformat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + wformat.Samples.wValidBitsPerSample=audio_out_format_bits(format); + } + + wformat.Format.nAvgBytesPerSec = wformat.Format.nSamplesPerSec * wformat.Format.nBlockAlign; //open sound device //WAVE_MAPPER always points to the default wave device on the system - result = waveOutOpen(&hWaveOut,WAVE_MAPPER,&wformat,(DWORD_PTR)waveOutProc,0,CALLBACK_FUNCTION); + result = waveOutOpen(&hWaveOut,WAVE_MAPPER,(WAVEFORMATEX*)&wformat,(DWORD_PTR)waveOutProc,0,CALLBACK_FUNCTION|WAVE_FORMAT_DIRECT); if(result == WAVERR_BADFORMAT) { mp_msg(MSGT_AO, MSGL_ERR,"ao_win32: format not supported switching to default\n"); - ao_data.channels = wformat.nChannels = 2; - ao_data.samplerate = wformat.nSamplesPerSec = 44100; + ao_data.channels = wformat.Format.nChannels = 2; + ao_data.samplerate = wformat.Format.nSamplesPerSec = 44100; ao_data.format = AFMT_S16_LE; - ao_data.bps=ao_data.channels * ao_data.samplerate*2; - ao_data.buffersize=wformat.wBitsPerSample=16; - wformat.nBlockAlign = wformat.nChannels * (wformat.wBitsPerSample >> 3); - wformat.nAvgBytesPerSec = wformat.nSamplesPerSec * wformat.nBlockAlign; - ao_data.buffersize/=8; - ao_data.buffersize*= ao_data.channels; - ao_data.buffersize*= SAMPLESIZE; - result = waveOutOpen(&hWaveOut,WAVE_MAPPER,&wformat,(DWORD_PTR)waveOutProc,0,CALLBACK_FUNCTION); + ao_data.bps=ao_data.channels * ao_data.samplerate*2; + wformat.Format.wBitsPerSample=16; + wformat.Format.wFormatTag=WAVE_FORMAT_PCM; + wformat.Format.nBlockAlign = wformat.Format.nChannels * (wformat.Format.wBitsPerSample >> 3); + wformat.Format.nAvgBytesPerSec = wformat.Format.nSamplesPerSec * wformat.Format.nBlockAlign; + ao_data.buffersize=(wformat.Format.wBitsPerSample>>3)*wformat.Format.nChannels*SAMPLESIZE; + result = waveOutOpen(&hWaveOut,WAVE_MAPPER,(WAVEFORMATEX*)&wformat,(DWORD_PTR)waveOutProc,0,CALLBACK_FUNCTION); } if(result != MMSYSERR_NOERROR) {