⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sndwin.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// --------------------------------------------------------------------------// Name: sndwin.cpp// Purpose:// Date: 08/11/1999// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000// CVSID: $Id: sndwin.cpp,v 1.12 2005/09/23 12:47:52 MR Exp $// wxWindows licence// --------------------------------------------------------------------------#include "wx/wxprec.h"#ifdef __WINDOWS__#ifndef WX_PRECOMP    #include "wx/defs.h"    #include "wx/app.h"    #include "wx/string.h"#endif#include "wx/module.h"#include "wx/msw/private.h"// -------------------------------------------------------------------------// MMedia headers// -------------------------------------------------------------------------#include "wx/mmedia/sndbase.h"#include "wx/mmedia/sndwin.h"#include "wx/mmedia/sndpcm.h"// -------------------------------------------------------------------------// System headers// -------------------------------------------------------------------------#include <windows.h>#include <mmsystem.h>// -------------------------------------------------------------------------// External definitions, forward, ...// -------------------------------------------------------------------------typedef struct _wxSoundInternal wxSoundInternal;typedef struct _wxSoundInfoHeader wxSoundInfoHeader;extern const wxChar *wxCanvasClassName;wxList *wxSoundHandleList = NULL;static inline wxSoundStreamWin *wxFindSoundFromHandle(WXHWND hWnd){  wxObjectList::compatibility_iterator node = wxSoundHandleList->Find((long)hWnd);  if (!node)    return NULL;  return (wxSoundStreamWin *)node->GetData();}struct _wxSoundInternal {  HWND m_sndWin;  HWAVEIN m_devin;  HWAVEOUT m_devout;  bool m_output_enabled, m_input_enabled;};struct _wxSoundInfoHeader {  HGLOBAL m_h_header, m_h_data;  char *m_data;  WAVEHDR *m_header;  int m_mode;  bool m_playing, m_recording;  wxUint32 m_position, m_size;  wxSoundStreamWin *m_driver;};#define WXSOUND_MAX_QUEUE 10wxSoundStreamWin::wxSoundStreamWin(){  wxSoundFormatPcm pcm;  m_production_started = false;  m_internal = new wxSoundInternal;  if (!m_internal) {    m_snderror = wxSOUND_MEMERROR;    m_internal = NULL;    return;  }  m_snderror = wxSOUND_NOERROR;  // 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)) {    m_snderror = wxSOUND_NOERROR; //next call to OpenDevice won't do this    if (!OpenDevice(wxSOUND_INPUT))      return;  }  CloseDevice();}wxSoundStreamWin::~wxSoundStreamWin(){  if (m_internal) {    if (m_production_started)      StopProduction();    DestroySndWindow();    delete m_internal;  }}// -----------------------------------------------------------------------// _wxSoundHandlerWndProc: Window callback to handle buffer completion// -----------------------------------------------------------------------LRESULT APIENTRY _EXPORT  _wxSoundHandlerWndProc(HWND hWnd, UINT message,                 WPARAM wParam, LPARAM WXUNUSED(lParam)){  wxSoundStreamWin *sndwin;  sndwin = wxFindSoundFromHandle((WXHWND)hWnd);  if (!sndwin)    return (LRESULT)0;  switch (message) {  case MM_WOM_DONE:    sndwin->NotifyDoneBuffer(wParam, wxSOUND_OUTPUT);    break;  case MM_WIM_DATA:    sndwin->NotifyDoneBuffer(wParam, wxSOUND_INPUT);    break;  default:    break;  }  return (LRESULT)0;}// -----------------------------------------------------------------------// CreateSndWindow() creates an hidden window which will receive the sound// events// -----------------------------------------------------------------------void wxSoundStreamWin::CreateSndWindow(){  FARPROC proc = MakeProcInstance((FARPROC)_wxSoundHandlerWndProc,                                  wxGetInstance());  // NB: class name must be kept in sync with wxCanvasClassName in   // src/msw/app.cpp!  m_internal->m_sndWin = ::CreateWindow(wxT("wxWindowClass"), NULL, 0,                    0, 0, 0, 0, NULL, (HMENU) NULL,                                        wxGetInstance(), NULL);  GetLastError();  ::SetWindowLong(m_internal->m_sndWin, GWL_WNDPROC, (LONG)proc);  // Add this window to the sound handle list so we'll be able to redecode  // the "magic" number.  wxSoundHandleList->Append((long)m_internal->m_sndWin, (wxObject *)this);}// -----------------------------------------------------------------------// DestroySndWindow() destroys the hidden window// -----------------------------------------------------------------------void wxSoundStreamWin::DestroySndWindow(){  if (m_internal->m_sndWin) {    ::DestroyWindow(m_internal->m_sndWin);    wxSoundHandleList->DeleteObject((wxObject *)this);  }}// -------------------------------------------------------------------------// OpenDevice(int mode) initializes the windows driver for a "mode"// operation. mode is a bit mask: if the bit "wxSOUND_OUTPUT" is set,// the driver is opened for output operation, and if the bit "wxSOUND_INPUT"// is set, then the driver is opened for input operation. The two modes// aren't exclusive.// The initialization parameters (sample rate, ...) are taken from the// m_sndformat object.// At the end, OpenDevice() calls AllocHeaders() to initialize the Sound IO// queue.// -------------------------------------------------------------------------bool wxSoundStreamWin::OpenDevice(int mode){  wxSoundFormatPcm *pcm;  WAVEFORMATEX wformat;  if (!m_sndformat) {    m_snderror = wxSOUND_INVFRMT;    return false;  }      pcm = (wxSoundFormatPcm *)m_sndformat;  wformat.wFormatTag      = WAVE_FORMAT_PCM;  wformat.nChannels       = pcm->GetChannels();  wformat.nBlockAlign     = wformat.nChannels * pcm->GetBPS() / 8;  wformat.nSamplesPerSec  = pcm->GetSampleRate();  wformat.nAvgBytesPerSec = wformat.nSamplesPerSec * wformat.nBlockAlign;  wformat.wBitsPerSample  = pcm->GetBPS();  wformat.cbSize          = 0;  // -----------------------------------  // Open the driver for Output operation  // -----------------------------------  if (mode & wxSOUND_OUTPUT) {    MMRESULT result;    result = waveOutOpen(&m_internal->m_devout,                         WAVE_MAPPER, &wformat,                         (DWORD)m_internal->m_sndWin, 0,                         CALLBACK_WINDOW);    if (result != MMSYSERR_NOERROR) {      m_snderror = wxSOUND_INVDEV;      return false;    }    m_output_frag_out  = WXSOUND_MAX_QUEUE-1;    m_current_frag_out = 0;    m_internal->m_output_enabled = true;  }  // -----------------------------------  // Open the driver for Input operation  // -----------------------------------  if (mode & wxSOUND_INPUT) {    MMRESULT result;    result = waveInOpen(&m_internal->m_devin,                        WAVE_MAPPER, &wformat,                        (DWORD)m_internal->m_sndWin, 0,                        CALLBACK_WINDOW);    if (result != MMSYSERR_NOERROR) {      m_snderror = wxSOUND_INVDEV;      return false;    }    m_current_frag_in = WXSOUND_MAX_QUEUE-1;    m_input_frag_in   = 0;    m_internal->m_input_enabled = true;  }  if (mode & wxSOUND_OUTPUT) {    if (!AllocHeaders(wxSOUND_OUTPUT)) {      CloseDevice();      return false;    }  }  if (mode & wxSOUND_INPUT) {    if (!AllocHeaders(wxSOUND_INPUT)) {      CloseDevice();      return false;    }  }  return true;}// -------------------------------------------------------------------------// CloseDevice() closes the driver handles and frees memory allocated for// IO queues.// -------------------------------------------------------------------------void wxSoundStreamWin::CloseDevice(){  if (m_internal->m_output_enabled) {    FreeHeaders(wxSOUND_OUTPUT);    m_internal->m_output_enabled = false;    waveOutClose(m_internal->m_devout);  }  if (m_internal->m_input_enabled) {    FreeHeaders(wxSOUND_INPUT);    m_internal->m_input_enabled  = false;    waveInClose(m_internal->m_devin);  }}// -------------------------------------------------------------------------// AllocHeader(int mode)//// mode has the same mean as in OpenDevice() except that here the two flags// must be exclusive.// AllocHeader() initializes an element of an operation (this can be input// or output). It means it allocates the sound header's memory block // and "prepares" it (It is needed by Windows). At the same time, it sets// private datas so we can the header's owner (See callback).//// It returns the new allocated block or NULL.// -------------------------------------------------------------------------wxSoundInfoHeader *wxSoundStreamWin::AllocHeader(int mode){  wxSoundInfoHeader *info;  WAVEHDR *header;  // Some memory allocation  info = new wxSoundInfoHeader;  info->m_h_data   = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, GetBestSize());  info->m_h_header = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(WAVEHDR));  if (!info->m_h_data || !info->m_h_header) {    delete info;    m_snderror = wxSOUND_MEMERROR;    return NULL;  }  // Get the two pointers from the system  info->m_data      = (char *)GlobalLock(info->m_h_data);  info->m_header    = (WAVEHDR *)GlobalLock(info->m_h_header);  // Set the header's mode  info->m_mode      = mode;  // Set the parent of the header  info->m_driver    = this;  // Clean it up  ClearHeader(info);  header            = info->m_header;  // Initialize Windows variables  header->lpData         = info->m_data;  header->dwBufferLength = GetBestSize();  header->dwUser         = (DWORD)info;  header->dwFlags        = WHDR_DONE;  // "Prepare" the header  if (mode == wxSOUND_INPUT) {    MMRESULT result;    result  = waveInPrepareHeader(m_internal->m_devin, header,                                  sizeof(WAVEHDR));    if (result != MMSYSERR_NOERROR) {      // If something goes wrong, free everything.      GlobalUnlock(info->m_data);      GlobalUnlock(info->m_header);      GlobalFree(info->m_h_data);      GlobalFree(info->m_h_header);      delete info;      m_snderror = wxSOUND_IOERROR;      return NULL;    }  } else if (mode == wxSOUND_OUTPUT) {    MMRESULT result;    result  = waveOutPrepareHeader(m_internal->m_devout, header,                                   sizeof(WAVEHDR));    if (result != MMSYSERR_NOERROR) {      // If something goes wrong, free everything.      GlobalUnlock(info->m_data);      GlobalUnlock(info->m_header);      GlobalFree(info->m_h_data);      GlobalFree(info->m_h_header);      delete info;      m_snderror = wxSOUND_IOERROR;      return NULL;    }  }  return info;}// -------------------------------------------------------------------------// AllocHeaders(int mode)//// "mode" has the same mean as for OpenDevice() except that the two flags must// be exclusive.// AllocHeaders() allocates WXSOUND_MAX_QUEUE (= 128) blocks for an operation// queue. It uses AllocHeader() for each element.//// Once it has allocated all blocks, it returns true and if an error occurred// it returns false.// -------------------------------------------------------------------------bool wxSoundStreamWin::AllocHeaders(int mode){  int i;  wxSoundInfoHeader **headers;  if (mode == wxSOUND_OUTPUT)    headers = m_headers_play = new wxSoundInfoHeader *[WXSOUND_MAX_QUEUE];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -