winealsa: Move start to the unixlib.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c32898c722
commit
1420d247a2
|
@ -1214,13 +1214,6 @@ static snd_pcm_sframes_t alsa_write_best_effort(struct alsa_stream *stream, BYTE
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS write_best_effort(void *args)
|
|
||||||
{
|
|
||||||
struct write_best_effort_tmp_params *params = args;
|
|
||||||
*params->written = alsa_write_best_effort(params->stream, params->buf, params->frames);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static snd_pcm_sframes_t alsa_write_buffer_wrap(struct alsa_stream *stream, BYTE *buf,
|
static snd_pcm_sframes_t alsa_write_buffer_wrap(struct alsa_stream *stream, BYTE *buf,
|
||||||
snd_pcm_uframes_t buflen, snd_pcm_uframes_t offs,
|
snd_pcm_uframes_t buflen, snd_pcm_uframes_t offs,
|
||||||
snd_pcm_uframes_t to_write)
|
snd_pcm_uframes_t to_write)
|
||||||
|
@ -1416,6 +1409,52 @@ exit:
|
||||||
NtSetEvent(stream->event, NULL);
|
NtSetEvent(stream->event, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS start(void *args)
|
||||||
|
{
|
||||||
|
struct start_params *params = args;
|
||||||
|
struct alsa_stream *stream = params->stream;
|
||||||
|
|
||||||
|
alsa_lock(stream);
|
||||||
|
|
||||||
|
if((stream->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) && !stream->event)
|
||||||
|
return alsa_unlock_result(stream, ¶ms->result, AUDCLNT_E_EVENTHANDLE_NOT_SET);
|
||||||
|
|
||||||
|
if(stream->started)
|
||||||
|
return alsa_unlock_result(stream, ¶ms->result, AUDCLNT_E_NOT_STOPPED);
|
||||||
|
|
||||||
|
if(stream->flow == eCapture){
|
||||||
|
/* dump any data that might be leftover in the ALSA capture buffer */
|
||||||
|
snd_pcm_readi(stream->pcm_handle, stream->local_buffer,
|
||||||
|
stream->bufsize_frames);
|
||||||
|
}else{
|
||||||
|
snd_pcm_sframes_t avail, written;
|
||||||
|
snd_pcm_uframes_t offs;
|
||||||
|
|
||||||
|
avail = snd_pcm_avail_update(stream->pcm_handle);
|
||||||
|
avail = min(avail, stream->held_frames);
|
||||||
|
|
||||||
|
if(stream->wri_offs_frames < stream->held_frames)
|
||||||
|
offs = stream->bufsize_frames - stream->held_frames + stream->wri_offs_frames;
|
||||||
|
else
|
||||||
|
offs = stream->wri_offs_frames - stream->held_frames;
|
||||||
|
|
||||||
|
/* fill it with data */
|
||||||
|
written = alsa_write_buffer_wrap(stream, stream->local_buffer,
|
||||||
|
stream->bufsize_frames, offs, avail);
|
||||||
|
|
||||||
|
if(written > 0){
|
||||||
|
stream->lcl_offs_frames = (offs + written) % stream->bufsize_frames;
|
||||||
|
stream->data_in_alsa_frames = written;
|
||||||
|
}else{
|
||||||
|
stream->lcl_offs_frames = offs;
|
||||||
|
stream->data_in_alsa_frames = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stream->started = TRUE;
|
||||||
|
|
||||||
|
return alsa_unlock_result(stream, ¶ms->result, S_OK);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS timer_loop(void *args)
|
static NTSTATUS timer_loop(void *args)
|
||||||
{
|
{
|
||||||
struct timer_loop_params *params = args;
|
struct timer_loop_params *params = args;
|
||||||
|
@ -1761,12 +1800,11 @@ unixlib_entry_t __wine_unix_call_funcs[] =
|
||||||
get_endpoint_ids,
|
get_endpoint_ids,
|
||||||
create_stream,
|
create_stream,
|
||||||
release_stream,
|
release_stream,
|
||||||
|
start,
|
||||||
timer_loop,
|
timer_loop,
|
||||||
is_format_supported,
|
is_format_supported,
|
||||||
get_mix_format,
|
get_mix_format,
|
||||||
get_buffer_size,
|
get_buffer_size,
|
||||||
get_latency,
|
get_latency,
|
||||||
get_current_padding,
|
get_current_padding,
|
||||||
|
|
||||||
write_best_effort /* temporary */
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -963,51 +963,6 @@ static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_sframes_t alsa_write_best_effort(struct alsa_stream *stream, BYTE *buf, snd_pcm_uframes_t frames)
|
|
||||||
{
|
|
||||||
struct write_best_effort_tmp_params params;
|
|
||||||
snd_pcm_sframes_t written;
|
|
||||||
|
|
||||||
params.stream = stream;
|
|
||||||
params.buf = buf;
|
|
||||||
params.frames = frames;
|
|
||||||
params.written = &written;
|
|
||||||
|
|
||||||
ALSA_CALL(write_best_effort_tmp, ¶ms);
|
|
||||||
|
|
||||||
return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
static snd_pcm_sframes_t alsa_write_buffer_wrap(struct alsa_stream *stream, BYTE *buf,
|
|
||||||
snd_pcm_uframes_t buflen, snd_pcm_uframes_t offs,
|
|
||||||
snd_pcm_uframes_t to_write)
|
|
||||||
{
|
|
||||||
snd_pcm_sframes_t ret = 0;
|
|
||||||
|
|
||||||
while(to_write){
|
|
||||||
snd_pcm_uframes_t chunk;
|
|
||||||
snd_pcm_sframes_t tmp;
|
|
||||||
|
|
||||||
if(offs + to_write > buflen)
|
|
||||||
chunk = buflen - offs;
|
|
||||||
else
|
|
||||||
chunk = to_write;
|
|
||||||
|
|
||||||
tmp = alsa_write_best_effort(stream, buf + offs * stream->fmt->nBlockAlign, chunk);
|
|
||||||
if(tmp < 0)
|
|
||||||
return ret;
|
|
||||||
if(!tmp)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ret += tmp;
|
|
||||||
to_write -= tmp;
|
|
||||||
offs += tmp;
|
|
||||||
offs %= buflen;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static snd_pcm_uframes_t interp_elapsed_frames(struct alsa_stream *stream)
|
static snd_pcm_uframes_t interp_elapsed_frames(struct alsa_stream *stream)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER time_freq, current_time, time_diff;
|
LARGE_INTEGER time_freq, current_time, time_diff;
|
||||||
|
@ -1053,7 +1008,7 @@ static int alsa_rewind_best_effort(ACImpl *This)
|
||||||
static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
|
static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
|
||||||
{
|
{
|
||||||
ACImpl *This = impl_from_IAudioClient3(iface);
|
ACImpl *This = impl_from_IAudioClient3(iface);
|
||||||
struct alsa_stream *stream = This->stream;
|
struct start_params params;
|
||||||
|
|
||||||
TRACE("(%p)\n", This);
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
|
@ -1064,60 +1019,18 @@ static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
|
||||||
return AUDCLNT_E_NOT_INITIALIZED;
|
return AUDCLNT_E_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
alsa_lock(stream);
|
params.stream = This->stream;
|
||||||
|
|
||||||
if((stream->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) && !stream->event){
|
ALSA_CALL(start, ¶ms);
|
||||||
alsa_unlock(stream);
|
|
||||||
LeaveCriticalSection(&g_sessions_lock);
|
|
||||||
return AUDCLNT_E_EVENTHANDLE_NOT_SET;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stream->started){
|
if(SUCCEEDED(params.result) && !This->timer_thread){
|
||||||
alsa_unlock(stream);
|
|
||||||
LeaveCriticalSection(&g_sessions_lock);
|
|
||||||
return AUDCLNT_E_NOT_STOPPED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stream->flow == eCapture){
|
|
||||||
/* dump any data that might be leftover in the ALSA capture buffer */
|
|
||||||
snd_pcm_readi(stream->pcm_handle, stream->local_buffer,
|
|
||||||
stream->bufsize_frames);
|
|
||||||
}else{
|
|
||||||
snd_pcm_sframes_t avail, written;
|
|
||||||
snd_pcm_uframes_t offs;
|
|
||||||
|
|
||||||
avail = snd_pcm_avail_update(stream->pcm_handle);
|
|
||||||
avail = min(avail, stream->held_frames);
|
|
||||||
|
|
||||||
if(stream->wri_offs_frames < stream->held_frames)
|
|
||||||
offs = stream->bufsize_frames - stream->held_frames + stream->wri_offs_frames;
|
|
||||||
else
|
|
||||||
offs = stream->wri_offs_frames - stream->held_frames;
|
|
||||||
|
|
||||||
/* fill it with data */
|
|
||||||
written = alsa_write_buffer_wrap(stream, stream->local_buffer,
|
|
||||||
stream->bufsize_frames, offs, avail);
|
|
||||||
|
|
||||||
if(written > 0){
|
|
||||||
stream->lcl_offs_frames = (offs + written) % stream->bufsize_frames;
|
|
||||||
stream->data_in_alsa_frames = written;
|
|
||||||
}else{
|
|
||||||
stream->lcl_offs_frames = offs;
|
|
||||||
stream->data_in_alsa_frames = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!This->timer_thread){
|
|
||||||
This->timer_thread = CreateThread(NULL, 0, alsa_timer_thread, This->stream, 0, NULL);
|
This->timer_thread = CreateThread(NULL, 0, alsa_timer_thread, This->stream, 0, NULL);
|
||||||
SetThreadPriority(This->timer_thread, THREAD_PRIORITY_TIME_CRITICAL);
|
SetThreadPriority(This->timer_thread, THREAD_PRIORITY_TIME_CRITICAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->started = TRUE;
|
|
||||||
|
|
||||||
alsa_unlock(stream);
|
|
||||||
LeaveCriticalSection(&g_sessions_lock);
|
LeaveCriticalSection(&g_sessions_lock);
|
||||||
|
|
||||||
return S_OK;
|
return params.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
|
static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
|
||||||
|
|
|
@ -91,6 +91,12 @@ struct release_stream_params
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct start_params
|
||||||
|
{
|
||||||
|
struct alsa_stream *stream;
|
||||||
|
HRESULT result;
|
||||||
|
};
|
||||||
|
|
||||||
struct timer_loop_params
|
struct timer_loop_params
|
||||||
{
|
{
|
||||||
struct alsa_stream *stream;
|
struct alsa_stream *stream;
|
||||||
|
@ -135,27 +141,18 @@ struct get_current_padding_params
|
||||||
UINT32 *padding;
|
UINT32 *padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct write_best_effort_tmp_params
|
|
||||||
{
|
|
||||||
struct alsa_stream *stream;
|
|
||||||
BYTE *buf;
|
|
||||||
snd_pcm_uframes_t frames;
|
|
||||||
snd_pcm_sframes_t *written;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum alsa_funcs
|
enum alsa_funcs
|
||||||
{
|
{
|
||||||
alsa_get_endpoint_ids,
|
alsa_get_endpoint_ids,
|
||||||
alsa_create_stream,
|
alsa_create_stream,
|
||||||
alsa_release_stream,
|
alsa_release_stream,
|
||||||
|
alsa_start,
|
||||||
alsa_timer_loop,
|
alsa_timer_loop,
|
||||||
alsa_is_format_supported,
|
alsa_is_format_supported,
|
||||||
alsa_get_mix_format,
|
alsa_get_mix_format,
|
||||||
alsa_get_buffer_size,
|
alsa_get_buffer_size,
|
||||||
alsa_get_latency,
|
alsa_get_latency,
|
||||||
alsa_get_current_padding,
|
alsa_get_current_padding,
|
||||||
|
|
||||||
alsa_write_best_effort_tmp
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern unixlib_handle_t alsa_handle;
|
extern unixlib_handle_t alsa_handle;
|
||||||
|
|
Loading…
Reference in New Issue