summaryrefslogtreecommitdiffstats
path: root/libao2/ao_dsound.c
diff options
context:
space:
mode:
authorfaust3 <faust3@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-10-18 19:23:13 +0000
committerfaust3 <faust3@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-10-18 19:23:13 +0000
commitae746ad8e8d49858a3f3f0ad5aff4b3173bce3bb (patch)
treefee719a288a5fdba1420044082ae3dbd30863052 /libao2/ao_dsound.c
parenta594e93e86c998f0abc8aa20d30a0981e75807a8 (diff)
downloadmpv-ae746ad8e8d49858a3f3f0ad5aff4b3173bce3bb.tar.bz2
mpv-ae746ad8e8d49858a3f3f0ad5aff4b3173bce3bb.tar.xz
channel reorder patch by Florian Dietrich <flodt8 at yahoo.de>
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13675 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libao2/ao_dsound.c')
-rw-r--r--libao2/ao_dsound.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/libao2/ao_dsound.c b/libao2/ao_dsound.c
index bfd5c1c232..dc23824c12 100644
--- a/libao2/ao_dsound.c
+++ b/libao2/ao_dsound.c
@@ -253,15 +253,6 @@ static int write_buffer(unsigned char *data, int len)
LPVOID lpvPtr2;
DWORD dwBytes2;
- DWORD play_offset;
- int space;
-
- // make sure we have enough space to write data
- IDirectSoundBuffer_GetCurrentPosition(hdsbuf,&play_offset,NULL);
- space=buffer_size-(write_offset-play_offset);
- if(space > buffer_size)space -= buffer_size; // write_offset < play_offset
- if(space < len) len = space;
-
// Lock the buffer
res = IDirectSoundBuffer_Lock(hdsbuf,write_offset, len, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
// If the buffer was lost, restore and retry lock.
@@ -274,11 +265,39 @@ static int write_buffer(unsigned char *data, int len)
if (SUCCEEDED(res))
{
- // Write to pointers.
+ if( (ao_data.channels == 6) && (ao_data.format!=AFMT_AC3) ) {
+ // reorder channels while writing to pointers.
+ // it's this easy because buffer size and len are always
+ // aligned to multiples of channels*bytespersample
+ // there's probably some room for speed improvements here
+ const int chantable[6] = {0, 1, 4, 5, 2, 3}; // reorder "matrix"
+ int i, j;
+ int numsamp,sampsize;
+
+ sampsize = audio_out_format_bits(ao_data.format)>>3; // bytes per sample
+ numsamp = dwBytes1 / (ao_data.channels * sampsize); // number of samples for each channel in this buffer
+
+ for( i = 0; i < numsamp; i++ ) for( j = 0; j < ao_data.channels; j++ ) {
+ memcpy(lpvPtr1+(i*ao_data.channels*sampsize)+(chantable[j]*sampsize),data+(i*ao_data.channels*sampsize)+(j*sampsize),sampsize);
+ }
+
+ if (NULL != lpvPtr2 )
+ {
+ numsamp = dwBytes2 / (ao_data.channels * sampsize);
+ for( i = 0; i < numsamp; i++ ) for( j = 0; j < ao_data.channels; j++ ) {
+ memcpy(lpvPtr2+(i*ao_data.channels*sampsize)+(chantable[j]*sampsize),data+dwBytes1+(i*ao_data.channels*sampsize)+(j*sampsize),sampsize);
+ }
+ }
+
+ write_offset+=dwBytes1+dwBytes2;
+ if(write_offset>=buffer_size)write_offset=dwBytes2;
+ } else {
+ // Write to pointers without reordering.
memcpy(lpvPtr1,data,dwBytes1);
if (NULL != lpvPtr2 )memcpy(lpvPtr2,data+dwBytes1,dwBytes2);
write_offset+=dwBytes1+dwBytes2;
if(write_offset>=buffer_size)write_offset=dwBytes2;
+ }
// Release the data back to DirectSound.
res = IDirectSoundBuffer_Unlock(hdsbuf,lpvPtr1,dwBytes1,lpvPtr2,dwBytes2);
@@ -409,6 +428,8 @@ static int init(int rate, int channels, int format, int flags)
res = IDirectSoundBuffer_SetFormat( hdspribuf, (WAVEFORMATEX *)&wformat );
if ( res != DS_OK ) mp_msg(MSGT_AO, MSGL_WARN,"ao_dsound: cannot set primary buffer format (%s), using standard setting (bad quality)", dserr2str(res));
+ mp_msg(MSGT_AO, MSGL_V, "ao_dsound: primary buffer created\n");
+
// now create the stream buffer
res = IDirectSound_CreateSoundBuffer(hds, &dsbdesc, &hdsbuf, NULL);
@@ -497,6 +518,15 @@ static int get_space()
*/
static int play(void* data, int len, int flags)
{
+ DWORD play_offset;
+ int space;
+
+ // make sure we have enough space to write data
+ IDirectSoundBuffer_GetCurrentPosition(hdsbuf,&play_offset,NULL);
+ space=buffer_size-(write_offset-play_offset);
+ if(space > buffer_size)space -= buffer_size; // write_offset < play_offset
+ if(space < len) len = space;
+
len = (len / ao_data.outburst) * ao_data.outburst;
return write_buffer(data, len);
}