9 #include "loader/wineacm.h"
11 #include "ad_internal.h"
12 #include "osdep/timer.h"
14 static ad_info_t info
=
30 static int init(sh_audio_t
*sh_audio
)
32 int ret
=decode_audio(sh_audio
,sh_audio
->a_buffer
,4096,sh_audio
->a_buffer_size
);
34 mp_msg(MSGT_DECAUDIO
,MSGL_INFO
,"ACM decoding error: %d\n",ret
);
37 sh_audio
->a_buffer_len
=ret
;
41 extern void print_wave_header(WAVEFORMATEX
*h
, int verbose_level
);
43 static int preinit(sh_audio_t
*sh_audio
)
46 WAVEFORMATEX
*in_fmt
= sh_audio
->wf
;
50 priv
= malloc(sizeof(acm_context_t
));
53 sh_audio
->context
= priv
;
55 mp_msg(MSGT_WIN32
, MSGL_V
, "======= Win32 (ACM) AUDIO Codec init =======\n");
57 // priv->handle = NULL;
59 priv
->o_wf
= malloc(sizeof(WAVEFORMATEX
));
62 mp_msg(MSGT_DECAUDIO
,MSGL_ERR
,MSGTR_ACMiniterror
);
66 priv
->o_wf
->nChannels
= in_fmt
->nChannels
;
67 priv
->o_wf
->nSamplesPerSec
= in_fmt
->nSamplesPerSec
;
68 priv
->o_wf
->nAvgBytesPerSec
= 2*in_fmt
->nSamplesPerSec
*in_fmt
->nChannels
;
69 priv
->o_wf
->wFormatTag
= WAVE_FORMAT_PCM
;
70 priv
->o_wf
->nBlockAlign
= 2*in_fmt
->nChannels
;
71 priv
->o_wf
->wBitsPerSample
= 16;
72 // priv->o_wf->wBitsPerSample = inf_fmt->wBitsPerSample;
73 priv
->o_wf
->cbSize
= 0;
75 if ( mp_msg_test(MSGT_DECAUDIO
,MSGL_V
) )
77 mp_msg(MSGT_DECAUDIO
, MSGL_V
, "Input format:\n");
78 print_wave_header(in_fmt
, MSGL_V
);
79 mp_msg(MSGT_DECAUDIO
, MSGL_V
, "Output format:\n");
80 print_wave_header(priv
->o_wf
, MSGL_V
);
83 MSACM_RegisterDriver((const char *)sh_audio
->codec
->dll
, in_fmt
->wFormatTag
, 0);
84 ret
= acmStreamOpen(&priv
->handle
, (HACMDRIVER
)NULL
, in_fmt
,
85 priv
->o_wf
, NULL
, 0, 0, 0);
88 if (ret
== ACMERR_NOTPOSSIBLE
)
89 mp_msg(MSGT_WIN32
, MSGL_ERR
, "ACM_Decoder: Unappropriate audio format\n");
91 mp_msg(MSGT_WIN32
, MSGL_ERR
, "ACM_Decoder: acmStreamOpen error: %d\n",
93 mp_msg(MSGT_DECAUDIO
,MSGL_ERR
,MSGTR_ACMiniterror
);
96 mp_msg(MSGT_WIN32
, MSGL_V
, "Audio codec opened OK! ;-)\n");
98 acmStreamSize(priv
->handle
, in_fmt
->nBlockAlign
, &srcsize
, ACM_STREAMSIZEF_SOURCE
);
99 //if ( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) printf("Audio ACM output buffer min. size: %ld (reported by codec)\n", srcsize);
101 //if (srcsize < MAX_OUTBURST) srcsize = MAX_OUTBURST;
104 mp_msg(MSGT_WIN32
, MSGL_WARN
, "Warning! ACM codec reports srcsize=0\n");
107 // limit srcsize to 4-16kb
108 //while(srcsize && srcsize<4096) srcsize*=2;
109 //while(srcsize>16384) srcsize/=2;
110 sh_audio
->audio_out_minsize
=srcsize
; // audio output min. size
111 mp_msg(MSGT_WIN32
,MSGL_V
,"Audio ACM output buffer min. size: %ld\n",srcsize
);
113 acmStreamSize(priv
->handle
, srcsize
, &srcsize
, ACM_STREAMSIZEF_DESTINATION
);
114 // if(srcsize<in_fmt->nBlockAlign) srcsize=in_fmt->nBlockAlign;
118 mp_msg(MSGT_WIN32
, MSGL_WARN
, "Warning! ACM codec reports srcsize=0\n");
119 srcsize
= 2*in_fmt
->nBlockAlign
;
122 mp_msg(MSGT_WIN32
,MSGL_V
,"Audio ACM input buffer min. size: %ld\n",srcsize
);
124 sh_audio
->audio_in_minsize
=2*srcsize
; // audio input min. size
126 sh_audio
->i_bps
=sh_audio
->wf
->nAvgBytesPerSec
;
127 sh_audio
->channels
=priv
->o_wf
->nChannels
;
128 sh_audio
->samplerate
=priv
->o_wf
->nSamplesPerSec
;
129 sh_audio
->samplesize
=2;
131 mp_msg(MSGT_DECVIDEO
,MSGL_V
,"INFO: Win32/ACM audio codec init OK!\n");
135 static void uninit(sh_audio_t
*sh
)
138 acm_context_t
*priv
= sh
->context
;
141 ret
= acmStreamClose(priv
->handle
, 0);
147 case ACMERR_CANCELED
:
148 mp_msg(MSGT_WIN32
, MSGL_DBG2
, "ACM_Decoder: stream busy, waiting..\n");
149 usec_sleep(100000000);
151 case ACMERR_UNPREPARED
:
152 case ACMERR_NOTPOSSIBLE
:
155 mp_msg(MSGT_WIN32
, MSGL_WARN
, "ACM_Decoder: unknown error occurred: %ld\n", ret
);
159 MSACM_UnregisterAllDrivers();
165 static int control(sh_audio_t
*sh_audio
,int cmd
,void* arg
, ...)
170 case ADCTRL_SKIP_FRAME
:
171 skip
=sh_audio
->wf
->nBlockAlign
;
173 skip
=(sh_audio
->wf
->nAvgBytesPerSec
/16)&(~7);
176 demux_read_data(sh_audio
->ds
,NULL
,skip
);
179 return CONTROL_UNKNOWN
;
182 static int decode_audio(sh_audio_t
*sh_audio
,unsigned char *buf
,int minlen
,int maxlen
)
188 acm_context_t
*priv
= sh_audio
->context
;
190 acmStreamSize(priv
->handle
, len
, &srcsize
, ACM_STREAMSIZEF_DESTINATION
);
191 mp_msg(MSGT_WIN32
,MSGL_DBG3
,"acm says: srcsize=%ld (buffsize=%d) out_size=%ld\n",srcsize
,sh_audio
->a_in_buffer_size
,len
);
193 if(srcsize
<sh_audio
->wf
->nBlockAlign
){
194 srcsize
=sh_audio
->wf
->nBlockAlign
;
195 acmStreamSize(priv
->handle
, srcsize
, &len
, ACM_STREAMSIZEF_SOURCE
);
196 if(len
>maxlen
) len
=maxlen
;
199 // if(srcsize==0) srcsize=((WAVEFORMATEX *)&sh_audio->o_wf_ext)->nBlockAlign;
200 if(srcsize
>sh_audio
->a_in_buffer_size
) srcsize
=sh_audio
->a_in_buffer_size
; // !!!!!!
201 if(sh_audio
->a_in_buffer_len
<srcsize
){
202 sh_audio
->a_in_buffer_len
+=
203 demux_read_data(sh_audio
->ds
,&sh_audio
->a_in_buffer
[sh_audio
->a_in_buffer_len
],
204 srcsize
-sh_audio
->a_in_buffer_len
);
206 mp_msg(MSGT_WIN32
,MSGL_DBG3
,"acm convert %d -> %ld bytes\n",sh_audio
->a_in_buffer_len
,len
);
207 memset(&ash
, 0, sizeof(ash
));
208 ash
.cbStruct
=sizeof(ash
);
211 ash
.pbSrc
=sh_audio
->a_in_buffer
;
212 ash
.cbSrcLength
=sh_audio
->a_in_buffer_len
;
215 hr
=acmStreamPrepareHeader(priv
->handle
,&ash
,0);
217 mp_msg(MSGT_WIN32
,MSGL_V
,"ACM_Decoder: acmStreamPrepareHeader error %d\n",(int)hr
);
220 hr
=acmStreamConvert(priv
->handle
,&ash
,0);
222 mp_msg(MSGT_WIN32
,MSGL_DBG2
,"ACM_Decoder: acmStreamConvert error %d\n",(int)hr
);
225 case ACMERR_NOTPOSSIBLE
:
226 case ACMERR_UNPREPARED
:
227 mp_msg(MSGT_WIN32
, MSGL_DBG2
, "ACM_Decoder: acmStreamConvert error: probarly not initialized!\n");
231 mp_msg(MSGT_WIN32
,MSGL_DBG2
,"acm converted %ld -> %ld\n",ash
.cbSrcLengthUsed
,ash
.cbDstLengthUsed
);
232 if(ash
.cbSrcLengthUsed
>=sh_audio
->a_in_buffer_len
){
233 sh_audio
->a_in_buffer_len
=0;
235 sh_audio
->a_in_buffer_len
-=ash
.cbSrcLengthUsed
;
236 memcpy(sh_audio
->a_in_buffer
,&sh_audio
->a_in_buffer
[ash
.cbSrcLengthUsed
],sh_audio
->a_in_buffer_len
);
238 len
=ash
.cbDstLengthUsed
;
239 hr
=acmStreamUnprepareHeader(priv
->handle
,&ash
,0);
241 mp_msg(MSGT_WIN32
,MSGL_V
,"ACM_Decoder: acmStreamUnprepareHeader error %d\n",(int)hr
);