winwave: poll mode
Signed-off-by: malc <av1474@comtv.ru>
This commit is contained in:
		
							parent
							
								
									d56316388d
								
							
						
					
					
						commit
						e0bda367e5
					
				@ -1,6 +1,7 @@
 | 
				
			|||||||
/* public domain */
 | 
					/* public domain */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
 | 
					#include "sysemu.h"
 | 
				
			||||||
#include "audio.h"
 | 
					#include "audio.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define AUDIO_CAP "winwave"
 | 
					#define AUDIO_CAP "winwave"
 | 
				
			||||||
@ -23,6 +24,7 @@ typedef struct {
 | 
				
			|||||||
    HWVoiceOut hw;
 | 
					    HWVoiceOut hw;
 | 
				
			||||||
    HWAVEOUT hwo;
 | 
					    HWAVEOUT hwo;
 | 
				
			||||||
    WAVEHDR *hdrs;
 | 
					    WAVEHDR *hdrs;
 | 
				
			||||||
 | 
					    HANDLE event;
 | 
				
			||||||
    void *pcm_buf;
 | 
					    void *pcm_buf;
 | 
				
			||||||
    int avail;
 | 
					    int avail;
 | 
				
			||||||
    int pending;
 | 
					    int pending;
 | 
				
			||||||
@ -120,6 +122,12 @@ static void CALLBACK winwave_callback (
 | 
				
			|||||||
                    wave->avail += conf.dac_samples;
 | 
					                    wave->avail += conf.dac_samples;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                LeaveCriticalSection (&wave->crit_sect);
 | 
					                LeaveCriticalSection (&wave->crit_sect);
 | 
				
			||||||
 | 
					                if (wave->hw.poll_mode) {
 | 
				
			||||||
 | 
					                    if (!SetEvent (wave->event)) {
 | 
				
			||||||
 | 
					                        AUD_log (AUDIO_CAP, "SetEvent failed %lx\n",
 | 
				
			||||||
 | 
					                                 GetLastError ());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -211,6 +219,7 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    WaveVoiceOut *wave = (WaveVoiceOut *) hw;
 | 
					    WaveVoiceOut *wave = (WaveVoiceOut *) hw;
 | 
				
			||||||
    int decr;
 | 
					    int decr;
 | 
				
			||||||
 | 
					    int doreset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EnterCriticalSection (&wave->crit_sect);
 | 
					    EnterCriticalSection (&wave->crit_sect);
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -221,6 +230,11 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    LeaveCriticalSection (&wave->crit_sect);
 | 
					    LeaveCriticalSection (&wave->crit_sect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    doreset = hw->poll_mode && (wave->pending >= conf.dac_samples);
 | 
				
			||||||
 | 
					    if (doreset && !ResetEvent (wave->event)) {
 | 
				
			||||||
 | 
					        AUD_log (AUDIO_CAP, "ResetEvent failed %lx\n", GetLastError ());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (wave->pending >= conf.dac_samples) {
 | 
					    while (wave->pending >= conf.dac_samples) {
 | 
				
			||||||
        MMRESULT mr;
 | 
					        MMRESULT mr;
 | 
				
			||||||
        WAVEHDR *h = &wave->hdrs[wave->curhdr];
 | 
					        WAVEHDR *h = &wave->hdrs[wave->curhdr];
 | 
				
			||||||
@ -235,6 +249,7 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
 | 
				
			|||||||
        wave->pending -= conf.dac_samples;
 | 
					        wave->pending -= conf.dac_samples;
 | 
				
			||||||
        wave->curhdr = (wave->curhdr + 1) % conf.dac_headers;
 | 
					        wave->curhdr = (wave->curhdr + 1) % conf.dac_headers;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return decr;
 | 
					    return decr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -249,15 +264,61 @@ static void winwave_fini_out (HWVoiceOut *hw)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    qemu_free (wave->hdrs);
 | 
					    qemu_free (wave->hdrs);
 | 
				
			||||||
    wave->hdrs = NULL;
 | 
					    wave->hdrs = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (wave->event) {
 | 
				
			||||||
 | 
					        if (!CloseHandle (wave->event)) {
 | 
				
			||||||
 | 
					            AUD_log (AUDIO_CAP, "CloseHandle failed %lx\n", GetLastError ());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        wave->event = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void winwave_poll_out (void *opaque)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    (void) opaque;
 | 
				
			||||||
 | 
					    audio_run ("winwave_poll_out");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
 | 
					static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    WaveVoiceOut *wave = (WaveVoiceOut *) hw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (cmd) {
 | 
					    switch (cmd) {
 | 
				
			||||||
    case VOICE_ENABLE:
 | 
					    case VOICE_ENABLE:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            va_list ap;
 | 
				
			||||||
 | 
					            int poll_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            va_start (ap, cmd);
 | 
				
			||||||
 | 
					            poll_mode = va_arg (ap, int);
 | 
				
			||||||
 | 
					            va_end (ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (poll_mode && !wave->event) {
 | 
				
			||||||
 | 
					                wave->event = CreateEvent (NULL, TRUE, TRUE, NULL);
 | 
				
			||||||
 | 
					                if (!wave->event) {
 | 
				
			||||||
 | 
					                    AUD_log (AUDIO_CAP,
 | 
				
			||||||
 | 
					                             "CreateEvent: %lx, poll mode will be disabled\n",
 | 
				
			||||||
 | 
					                             GetLastError ());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (wave->event) {
 | 
				
			||||||
 | 
					                int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ret = qemu_add_wait_object (wave->event, winwave_poll_out,
 | 
				
			||||||
 | 
					                                            wave);
 | 
				
			||||||
 | 
					                hw->poll_mode = (ret == 0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                hw->poll_mode = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case VOICE_DISABLE:
 | 
					    case VOICE_DISABLE:
 | 
				
			||||||
 | 
					        if (wave->event) {
 | 
				
			||||||
 | 
					            qemu_del_wait_object (wave->event, winwave_poll_out, wave);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user