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

📄 sndwin.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  else    headers = m_headers_rec = new wxSoundInfoHeader *[WXSOUND_MAX_QUEUE];  memset(headers, 0, WXSOUND_MAX_QUEUE*sizeof(wxSoundInfoHeader *));  for (i=0;i<WXSOUND_MAX_QUEUE;i++) {    headers[i] = AllocHeader(mode);    if (!headers[i]) {      FreeHeaders(mode);      return false;    }  }  return true;}// -------------------------------------------------------------------------// FreeHeader(int mode)//// "mode" has the same mean as for OpenDevice() except that the two flags must// be exclusive.// FreeHeader() frees a memory block and "unprepares" it.// -------------------------------------------------------------------------void wxSoundStreamWin::FreeHeader(wxSoundInfoHeader *header, int mode){  if (mode == wxSOUND_OUTPUT)    waveOutUnprepareHeader(m_internal->m_devout, header->m_header, sizeof(WAVEHDR));  else    waveInUnprepareHeader(m_internal->m_devin, header->m_header, sizeof(WAVEHDR));  GlobalUnlock(header->m_data);  GlobalUnlock(header->m_header);  GlobalFree(header->m_h_header);  GlobalFree(header->m_h_data);  delete header;}// -------------------------------------------------------------------------// FreeHeaders(int mode)//// "mode" has the same mean as for OpenDevice() except that the two flags must// be exclusive.// FreeHeaders() frees all an operation queue once it has checked that// all buffers have been terminated.// -------------------------------------------------------------------------void wxSoundStreamWin::FreeHeaders(int mode){  int i;  wxSoundInfoHeader ***headers;  if (mode == wxSOUND_OUTPUT)    headers = &m_headers_play;  else    headers = &m_headers_rec;  for (i=0;i<WXSOUND_MAX_QUEUE;i++) {    if ((*headers)[i]) {      // We wait for the end of the buffer      WaitFor((*headers)[i]);      // Then, we free the header      FreeHeader((*headers)[i], mode);    }  }  delete[] (*headers);  (*headers) = NULL;}// -------------------------------------------------------------------------// WaitFor(wxSoundInfoHeader *info)//// "info" is one element of an IO queue// WaitFor() checks whether the specified block has been terminated.// If it hasn't been terminated, it waits for its termination.//// NB: if it's a partially filled buffer it adds it to the Windows queue// -------------------------------------------------------------------------void wxSoundStreamWin::WaitFor(wxSoundInfoHeader *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 (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;}// -------------------------------------------------------------------------// AddToQueue(wxSoundInfoHeader *info)//// For "info", see WaitFor()// AddToQueue() sends the IO queue element to the Windows queue.//// Warning: in the current implementation, it partially assume we send the// element in the right order. This is true in that implementation but if// you use it elsewhere, be careful: it may shuffle all your sound datas.// -------------------------------------------------------------------------bool wxSoundStreamWin::AddToQueue(wxSoundInfoHeader *info){    MMRESULT result;        if (info->m_mode == wxSOUND_INPUT) {        // Increment the input fragment pointer        result = waveInAddBuffer(m_internal->m_devin,                                 info->m_header, sizeof(WAVEHDR));        if (result == MMSYSERR_NOERROR)            info->m_recording = true;        else            return false;    } else if (info->m_mode == wxSOUND_OUTPUT) {        result = waveOutWrite(m_internal->m_devout,                              info->m_header, sizeof(WAVEHDR));        if (result == MMSYSERR_NOERROR)      info->m_playing = true;        else            return false;    }    return true;}// -------------------------------------------------------------------------// ClearHeader(wxSoundInfoHeader *info)//// ClearHeader() reinitializes the parameters of "info" to their default// value.// -------------------------------------------------------------------------void wxSoundStreamWin::ClearHeader(wxSoundInfoHeader *info){  info->m_playing   = false;  info->m_recording = false;  info->m_position  = 0;  info->m_size      = GetBestSize();}// -------------------------------------------------------------------------// wxSoundInfoHeader *NextFragmentOutput()//// NextFragmentOutput() looks for a free output block. It will always// return you a non-NULL pointer but it may waits for an empty buffer a long// time.// -------------------------------------------------------------------------wxSoundInfoHeader *wxSoundStreamWin::NextFragmentOutput(){  if (m_headers_play[m_current_frag_out]->m_playing) {    m_current_frag_out = (m_current_frag_out + 1) % WXSOUND_MAX_QUEUE;    if (m_headers_play[m_current_frag_out]->m_playing)      WaitFor(m_headers_play[m_current_frag_out]);  }  if (m_current_frag_out == m_output_frag_out)    m_queue_filled = true;  return m_headers_play[m_current_frag_out];}// -------------------------------------------------------------------------// The behaviour of Write is documented in the global documentation.// -------------------------------------------------------------------------wxSoundStream& wxSoundStreamWin::Write(const void *buffer, wxUint32 len){    m_lastcount = 0;    if (!m_internal->m_output_enabled) {        m_snderror = wxSOUND_NOTSTARTED;        return *this;    }        while (len > 0) {        wxSoundInfoHeader *header;        wxUint32 to_copy;                // Get a new output fragment        header              = NextFragmentOutput();                to_copy             = (len > header->m_size) ? header->m_size : len;        memcpy(header->m_data + header->m_position, buffer, to_copy);                header->m_position += to_copy;        header->m_size     -= to_copy;        buffer              = (((const char *)buffer) + to_copy);        len                -= to_copy;        m_lastcount        += to_copy;                // If the fragment is full, we send it to the Windows queue.        if (header->m_size == 0)            if (!AddToQueue(header)) {                m_snderror = wxSOUND_IOERROR;                return *this;            }    }    return *this;}// -------------------------------------------------------------------------// NextFragmentInput is not functional.// -------------------------------------------------------------------------wxSoundInfoHeader *wxSoundStreamWin::NextFragmentInput(){    wxSoundInfoHeader *header;    // Queue pointer: reader    m_current_frag_in = (m_current_frag_in + 1) % WXSOUND_MAX_QUEUE;        header = m_headers_rec[m_current_frag_in];    // If the current buffer is in recording mode, we must wait for its    // completion.    if (header->m_recording)        WaitFor(header);    // We reached the writer position: the queue is full.    if (m_current_frag_in == m_input_frag_in)        m_queue_filled = true;        return header;}// -------------------------------------------------------------------------// The behaviour of Read is documented in the global documentation.// -------------------------------------------------------------------------wxSoundStream& wxSoundStreamWin::Read(void *buffer, wxUint32 len){    wxSoundInfoHeader *header;    wxUint32 to_copy;        m_lastcount = 0;    if (!m_internal->m_input_enabled)        return *this;        while (len > 0) {        header = NextFragmentInput();                to_copy             = (len > header->m_size) ? header->m_size : len;        memcpy(buffer, header->m_data + header->m_position, to_copy);                header->m_position += to_copy;        header->m_size     -= to_copy;        buffer              = (((char *)buffer) + to_copy);        len                -= to_copy;        m_lastcount        += to_copy;                if (header->m_size == 0) {            ClearHeader(header);            if (!AddToQueue(header)) {                m_snderror = wxSOUND_IOERROR;                return *this;            }        }    }    return *this;}// -------------------------------------------------------------------------// NotifyDoneBuffer(wxUint32 dev_handle)//// NotifyDoneBuffer() is called by wxSoundHandlerProc each time a sound// fragment finished. It reinitializes the parameters of the fragment and// sends an event to the clients.// -------------------------------------------------------------------------void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 WXUNUSED(dev_handle), int flag){    wxSoundInfoHeader *info;        if (flag == wxSOUND_OUTPUT) {        if (!m_internal->m_output_enabled)            return;        // Queue pointer: reader        m_output_frag_out = (m_output_frag_out + 1) % WXSOUND_MAX_QUEUE;        info = m_headers_play[m_output_frag_out];        // Clear header to tell the system the buffer is free now        ClearHeader(info);        m_queue_filled = false;        if (!m_waiting_for)            // Try to requeue a new buffer.            OnSoundEvent(wxSOUND_OUTPUT);    } else {        if (!m_internal->m_input_enabled)            return;        // Recording completed        m_headers_rec[m_input_frag_in]->m_recording = false;        // Queue pointer: writer        m_input_frag_in = (m_input_frag_in + 1) % WXSOUND_MAX_QUEUE;        if (!m_waiting_for)            OnSoundEvent(wxSOUND_INPUT);        m_queue_filled = false;    }}// -------------------------------------------------------------------------// SetSoundFormat()// -------------------------------------------------------------------------bool wxSoundStreamWin::SetSoundFormat(const wxSoundFormatBase& base){  // TODO: detect best format  return wxSoundStream::SetSoundFormat(base);}// -------------------------------------------------------------------------// StartProduction()// -------------------------------------------------------------------------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();  if (!OpenDevice(evt))    return false;  m_production_started = true;  m_queue_filled = false;  // Send a dummy event to start.  if (evt & wxSOUND_OUTPUT)    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;}// -------------------------------------------------------------------------// StopProduction()// ------------------------------------------------------------------------bool wxSoundStreamWin::StopProduction(){    if (!m_production_started) {        m_snderror = wxSOUND_NOTSTARTED;        return false;    }        m_snderror = wxSOUND_NOERROR;    m_production_started = false;    CloseDevice();    return true;}// -------------------------------------------------------------------------// QueueFilled()// -------------------------------------------------------------------------bool wxSoundStreamWin::QueueFilled() const{  return (!m_production_started || m_queue_filled);}// --------------------------------------------------------------------------// wxSoundWinModule// --------------------------------------------------------------------------class wxSoundWinModule : public wxModule {   DECLARE_DYNAMIC_CLASS(wxSoundWinModule) public:   bool OnInit();   void OnExit();};IMPLEMENT_DYNAMIC_CLASS(wxSoundWinModule, wxModule)bool wxSoundWinModule::OnInit() {  wxSoundHandleList = new wxList(wxKEY_INTEGER);  return true;}void wxSoundWinModule::OnExit() {  delete wxSoundHandleList;}#endif  // __WINDOWS__

⌨️ 快捷键说明

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