typedef struct _wxSoundInternal wxSoundInternal;
typedef struct _wxSoundInfoHeader wxSoundInfoHeader;
-extern char wxCanvasClassName[];
+extern const wxChar *wxCanvasClassName;
wxList *wxSoundHandleList = NULL;
wxSoundStreamWin *m_driver;
};
-#define WXSOUND_MAX_QUEUE 128
+#define WXSOUND_MAX_QUEUE 10
wxSoundStreamWin::wxSoundStreamWin()
{
m_production_started = FALSE;
m_internal = new wxSoundInternal;
+ if (!m_internal) {
+ m_snderror = wxSOUND_MEMERR;
+ m_internal = NULL;
+ return;
+ }
m_snderror = wxSOUND_NOERR;
// Setup defaults
CreateSndWindow();
SetSoundFormat(pcm);
+ m_internal->m_input_enabled = FALSE;
+ m_internal->m_output_enabled = FALSE;
+
+ m_waiting_for = FALSE;
+
if (!OpenDevice(wxSOUND_OUTPUT))
return;
wxSoundStreamWin::~wxSoundStreamWin()
{
- if (m_production_started)
- StopProduction();
- DestroySndWindow();
+ if (m_internal) {
+ if (m_production_started)
+ StopProduction();
+ DestroySndWindow();
- delete m_internal;
+ delete m_internal;
+ }
}
LRESULT APIENTRY _EXPORT _wxSoundHandlerWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
+ wxSoundStreamWin *sndwin;
+
+ sndwin = wxFindSoundFromHandle((WXHWND)hWnd);
+ if (!sndwin)
+ return (LRESULT)0;
+
switch (message) {
- case MM_WOM_DONE: {
- wxFindSoundFromHandle((WXHWND)hWnd)->NotifyDoneBuffer(wParam);
+ case MM_WOM_DONE:
+ sndwin->NotifyDoneBuffer(wParam, wxSOUND_OUTPUT);
+ break;
+ case MM_WIM_DATA:
+ sndwin->NotifyDoneBuffer(wParam, wxSOUND_INPUT);
break;
- }
default:
break;
}
wformat.wFormatTag = WAVE_FORMAT_PCM;
wformat.nChannels = pcm->GetChannels();
- wformat.nBlockAlign = pcm->GetBPS() / 8 * wformat.nChannels;
- wformat.nAvgBytesPerSec = pcm->GetBytesFromTime(1);
+ wformat.nBlockAlign = wformat.nChannels * pcm->GetBPS() / 8;
wformat.nSamplesPerSec = pcm->GetSampleRate();
+ wformat.nAvgBytesPerSec = wformat.nSamplesPerSec * wformat.nBlockAlign;
wformat.wBitsPerSample = pcm->GetBPS();
wformat.cbSize = 0;
return FALSE;
}
- m_input_frag_in = WXSOUND_MAX_QUEUE-1;
- m_current_frag_in = 0;
+ m_current_frag_in = WXSOUND_MAX_QUEUE-1;
+ m_input_frag_in = 0;
m_internal->m_input_enabled = TRUE;
}
- if (!AllocHeaders(mode)) {
- CloseDevice();
- return FALSE;
+ if (mode & wxSOUND_OUTPUT) {
+ if (!AllocHeaders(wxSOUND_OUTPUT)) {
+ CloseDevice();
+ return FALSE;
+ }
+ }
+ if (mode & wxSOUND_INPUT) {
+ if (!AllocHeaders(wxSOUND_INPUT)) {
+ CloseDevice();
+ return FALSE;
+ }
}
+
return TRUE;
}
{
if (m_internal->m_output_enabled) {
FreeHeaders(wxSOUND_OUTPUT);
- waveOutReset(m_internal->m_devout);
+ m_internal->m_output_enabled = FALSE;
waveOutClose(m_internal->m_devout);
}
if (m_internal->m_input_enabled) {
FreeHeaders(wxSOUND_INPUT);
- waveInReset(m_internal->m_devin);
+ m_internal->m_input_enabled = FALSE;
waveInClose(m_internal->m_devin);
}
-
- m_internal->m_output_enabled = FALSE;
- m_internal->m_input_enabled = FALSE;
}
// -------------------------------------------------------------------------
header->dwUser = (DWORD)info;
header->dwFlags = WHDR_DONE;
-
// "Prepare" the header
if (mode == wxSOUND_INPUT) {
MMRESULT result;
// -------------------------------------------------------------------------
void wxSoundStreamWin::WaitFor(wxSoundInfoHeader *info)
{
- // We begun filling it: we must send it to the Windows queue
- if (info->m_position != 0) {
- memset(info->m_data + info->m_position, 0, info->m_size-info->m_position);
- AddToQueue(info);
+ // If the buffer is finished, we return immediately
+ if (!info->m_playing) {
+
+ // We begun filling it: we must send it to the Windows queue
+ if (info->m_position != 0) {
+ memset(info->m_data + info->m_position, 0, info->m_size);
+ AddToQueue(info);
+ }
}
- // If the buffer is finished, we return immediately
- if (!info->m_playing && !info->m_recording)
+ if (m_waiting_for) {
+ // PROBLEM //
return;
-
+ }
+ m_waiting_for = TRUE;
// Else, we wait for its termination
while (info->m_playing || info->m_recording)
wxYield();
+ m_waiting_for = FALSE;
}
// -------------------------------------------------------------------------
if (info->m_mode == wxSOUND_INPUT) {
// Increment the input fragment pointer
- m_current_frag_in = (m_current_frag_in + 1) % WXSOUND_MAX_QUEUE;
result = waveInAddBuffer(m_internal->m_devin,
info->m_header, sizeof(WAVEHDR));
if (result == MMSYSERR_NOERROR)
{
wxSoundInfoHeader *header;
- // TODO //
+ m_current_frag_in = (m_current_frag_in + 1) % WXSOUND_MAX_QUEUE;
+
header = m_headers_rec[m_current_frag_in];
- WaitFor(header);
+ if (header->m_recording)
+ WaitFor(header);
if (m_current_frag_in == m_input_frag_in)
m_queue_filled = TRUE;
// fragment finished. It reinitializes the parameters of the fragment and
// sends an event to the clients.
// -------------------------------------------------------------------------
-void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle)
+void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle, int flag)
{
wxSoundInfoHeader *info;
- if (dev_handle == (wxUint32)m_internal->m_devout) {
+ if (flag == wxSOUND_OUTPUT) {
+ if (!m_internal->m_output_enabled)
+ return;
+
m_output_frag_out = (m_output_frag_out + 1) % WXSOUND_MAX_QUEUE;
info = m_headers_play[m_output_frag_out];
ClearHeader(info);
m_queue_filled = FALSE;
- OnSoundEvent(wxSOUND_OUTPUT);
+ if (!m_waiting_for)
+ OnSoundEvent(wxSOUND_OUTPUT);
} else {
+ if (!m_internal->m_input_enabled)
+ return;
+
+ m_headers_rec[m_input_frag_in]->m_recording = FALSE;
m_input_frag_in = (m_input_frag_in + 1) % WXSOUND_MAX_QUEUE;
- OnSoundEvent(wxSOUND_INPUT);
+ if (!m_waiting_for)
+ OnSoundEvent(wxSOUND_INPUT);
m_queue_filled = FALSE;
}
}
// -------------------------------------------------------------------------
bool wxSoundStreamWin::StartProduction(int evt)
{
+ if (!m_internal)
+ return FALSE;
+
if ((m_internal->m_output_enabled && (evt & wxSOUND_OUTPUT)) ||
(m_internal->m_input_enabled && (evt & wxSOUND_INPUT)))
CloseDevice();
m_queue_filled = FALSE;
// Send a dummy event to start.
if (evt & wxSOUND_OUTPUT)
- OnSoundEvent(evt);
+ OnSoundEvent(wxSOUND_OUTPUT);
if (evt & wxSOUND_INPUT) {
int i;
for (i=0;i<WXSOUND_MAX_QUEUE;i++)
AddToQueue(m_headers_rec[i]);
+
+ waveInStart(m_internal->m_devin);
}
return TRUE;
// -------------------------------------------------------------------------
bool wxSoundStreamWin::StopProduction()
{
+ if (!m_production_started)
+ return FALSE;
+
m_production_started = FALSE;
CloseDevice();
return TRUE;