На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела "Программирование звука"
0) Данный раздел предназначен для обсуждения проблем, возникающих при программировании задач, связанных с записью, обработкой, воспроизведением звука. Перед созданием темы подумайте, не будет ли она уместнее в разделах Разработка и тестирование программ, Наши исходники, а особенно Разовые заказы и подработки
1) На Раздел распространяются все Правила форума.Огромная просьба с ними внимательно ознакомиться.
2) Запрещается давать бессмысленные ответы вроде: "Снеси Мастдай", "ХП рулит", "Поставь Линукс" и т.д.
3) Запрещается создавать темы, в которых Вы намереваетесь получить ссылку на кряки, серийники и т.п. Также запрещено любое обсуждение p2p (peer-to-peer) сетей (BitTorrent, eDonkey и т.д.).
4) Реклама всякого рода пресекается беспощадно.
5) Используйте тэг [CODE] для выделения кода программы (непременно с указанием языка программирования - выбрать из списка. В противном случае бессмысленно!). Уважайте тех, кто будет читать ваш код!
6) Если решение вашей проблемы найдено, то не забываем помечать тему специальной функцией "Вопрос решён". Вам всего лишь требуется при написании последнего ответа поставить одну единственную галочку прямо над формой ответа.
7) Если вы хотите получить совет для конкретной платформы/языка программирования, обязательно укажите их в вопросе

8) Если не прикрепляются/не скачиваются файлы, читаем Не прикрепляется / не скачивается файл. Любые обсуждения в данном разделе проблем с приложением файлов считаются оффтопиком! Со всеми вытекающими.

9) NEW! Уважаемые новички! Мы приветствуем Ваше желание научить всех посетителей раздела правильному программированию. Но огромная просьба, перед тем, как писать поучения в старых (последний ответ - "старее" месяца, а особенно, если вопрошавший не появляется на форуме уже не первый месяц, в чем можно убедиться в его профиле) темах, хорошо подумать, будет ли кому-нибудь, кроме Вас cамих, это интересно. Попытки накрутки количества тематических сообщений за счёт поднятия древних неактуальных тем ("некрофилия") будут наказываться по велению левой пятки модераторского состава (см. пп.12, 13 Правил)



Нарушение Правил может повлечь наказание со стороны модераторов.



user posted imageFAQ Раздела user posted imageПоиск в Разделе user posted imageMSDN Library Online | Ваше мнение о модераторах: user posted imageBarazuk user posted imageRikkie
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> waveOutWrite и пауза (+вопрос про ошибку)
    http://msdn.microsoft.com/en-us/library/wi...6(v=vs.85).aspx
    Цитата
    Unless the device is paused by calling the waveOutPause function, playback begins when the first data block is sent to the device.

    Подскажите что там написано.
    1 Когда устройство стоит на паузе, вызов waveOutWrite записывает буфер в очередь не запуская воспроизведение (устройство остается на паузе)
    2 Когда устройство стоит на паузе, вызов waveOutWrite запускает воспроизведение буфера.



    И у меня еще один вопрос про ошибку:

    waveOutWrite
    возвращает десятичное значение 33. Я нашел описание ошибок только до 21. Как мне узнать описание этой ошибки?
    Сообщение отредактировано: Суровый -
      Цитата Суровый @
      Подскажите что там написано.
      "Хотя устройство и находится на паузе, в ожидании завершения выхода из функции waveOutWrite, воспроизведение начнётся как токмо первые данные придут в него, в устройство."

      Добавлено
      Цитата Суровый @
      waveOutWrite возвращает десятичное значение 33. Я нашел описание ошибок только до 21. Как мне узнать описание этой ошибки?
      Наверное, там якобы-битовые разделы:
      ExpandedWrap disabled
        #define MMSYSERR_BASE          0
        #define WAVERR_BASE            32
        #define MIDIERR_BASE           64
        #define TIMERR_BASE            96
        #define JOYERR_BASE            160
        #define MCIERR_BASE            256
        #define MIXERR_BASE            1024
      А потому ваша ошибка 33 означает, что проблема с WAVE-форматом, №1, т.е.
      ExpandedWrap disabled
        #define MMSYSERR_ERROR        (MMSYSERR_BASE + 1)  /* unspecified error */


      Добавлено
      Цитата Славян @
      там якобы-битовые разделы
      Тьфу, виноват, слово 'якобы' надо зачеркнуть. :blush: Как-то мой мозг быстро не смог поделить 160 на 32, а оказывается делится! Всё нормально: первые 5 бит - на детали ошибки, старшие - на раздел/суть оной. :yes:
        Цитата
        Подскажите что там написано.

        Что если устройство не "поставлено на паузу" вызовом соотвествующей функции, то воспроизведение начинается сразу после того, как устроству передан блок данных.
          Постовил я 33-ю ошибку на игнор, и всё заработало как надо.
          Тут Славян подсказал что надо смотреть WAVERR_ а не MMSYSERR_. И действительно оказалось, что это "Сейчас что-то уже играет".

          Собственно что из этого:
          Цитата Славян @
          "Хотя устройство и находится на паузе, в ожидании завершения выхода из функции waveOutWrite, воспроизведение начнётся как токмо первые данные придут в него, в устройство."

          вытекает 1 или 2?

          Добавлено
          Prince, ясно спасибо.
            Цитата Суровый @
            Собственно что из этого:
            ...
            вытекает 1 или 2?
            Увы, я не понял вопроса. :(
              Вопросы решены.

              Славян, вытекает 1 (усройство остается на паузе). Плюсик я тебе завтра поставлю.
                Цитата
                Постовил я 33-ю ошибку на игнор, и всё заработало как надо.

                Цитата
                Вопросы решены.

                :scratch:
                  Цитата Суровый @
                  Плюсик я тебе завтра поставлю.
                  Э-э-э
                  Забейте. Зачтём сегодняшний, политический, как два по поллитра: 1=2*0,5 ;)
                    Prince, 33 это по сути не ошибка, а сообщение, что что-то уже(еще) игрет

                    Добавлено
                    ExpandedWrap disabled
                      #define WAVERR_STILLPLAYING   (WAVERR_BASE + 1)    /* still something playing */
                      Цитата Prince @
                      Цитата
                      Постовил я 33-ю ошибку на игнор, и всё заработало как надо.
                      Цитата
                      Вопросы решены.
                      :scratch:
                      :lool: А вы думали! Силён наш Суровый, силён! :)
                        Цитата
                        это по сути не ошибка

                        Точно-точно?
                        Майкрософт говорит, что waveoutwrite вообще такое не умеет возвращать в качестве результата, хотя может у меня sdk устаревший. :-?
                        В любом случае, имхо, стоит разобраться, что оно означает, это сообщение, и почему вылазит.
                        Может, покажете послеовательность действий?
                          Цитата Prince @
                          В любом случае, имхо, стоит разобраться, что оно означает, это сообщение, и почему вылазит.
                          Может, покажете послеовательность действий?

                          Мне не принципиально. Но если интересно то вот:
                          AudioUnit.h
                          ExpandedWrap disabled
                            //---------------------------------------------------------------------------
                             
                            #ifndef AudioUnitH
                            #define AudioUnitH
                            //
                            #include "UtilUnit.h"
                            #include "mmsystem.hpp"
                            #include "DataUnit.h"
                            #include <Classes.hpp>
                             
                            //
                            class CPlayer;
                             
                            class CBuffer {
                                private:
                                    AudioFmt Fmt;
                                    int Size;
                                    int Rate;
                             
                                    void *WO;
                                    char *Buf;
                                    WAVEHDR WH[2];
                                public:
                                    CBuffer(AudioFmt aFmt, int aSize, int aRate);
                                    ~CBuffer();
                             
                                    void Play(int n);
                                    void Pause();
                                    void Restart();
                                    void Reset();
                             
                                    void SetVol(int aVol);
                             
                                    CPlayer *pPlayer;
                             
                                    int GetBufNum(void *P);
                                    void *GetBufPtr(int N);
                            };
                             
                            class CPlayTh: public TThread {
                                private:
                                    CPlayer *Player;
                                    HANDLE SignalDone;
                                public:
                                    CPlayTh(CPlayer *aPlayer);
                             
                                    void __fastcall Execute();
                             
                                    void Done();
                            };
                             
                            enum TPlayMsg {PM_DONE_BUF,PM_DONE_FILE};
                             
                            class CPlayer {
                                private:
                                  CBuffer *Buf;
                                  CWAVE *Wav;
                                  CPlayTh *Th;
                             
                                  int nBuf;
                                  bool Paused;
                                  bool Played;
                                  TRTLCriticalSection CS;
                             
                                  HWND Wnd;
                             
                                  void LoadNextFrame(int nBuf);
                                public:
                                  CPlayer(CWAVE *aWav, HWND W=0);
                                  ~CPlayer();
                             
                                  void DoneBuf(int n);
                                  void __fastcall LoadTh();
                             
                                  void SetPos(int nPos);
                                  void SetVol(int aVol);
                             
                                  void Play();
                                  void Pause();
                            };
                            //---------------------------------------------------------------------------
                            #endif

                          AudioUnit.cpp
                          ExpandedWrap disabled
                            //---------------------------------------------------------------------------
                             
                             
                            #pragma hdrstop
                             
                            #include "AudioUnit.h"
                            #include <mmsystem.hpp>
                             
                            //---------------------------------------------------------------------------
                             
                            #pragma package(smart_init)
                             
                            void CALLBACK waveOutCallBack(int WO, UINT Msg, CBuffer *P, void *a1, int a2)
                            {
                                if (Msg==WOM_DONE)
                                    if (P->pPlayer!=NULL)
                                        P->pPlayer->DoneBuf( P->GetBufNum(a1) );
                            }
                             
                            CBuffer::CBuffer(AudioFmt aFmt, int aSize, int aRate) {
                                Fmt = aFmt;
                                Size = aSize;
                                Rate = aRate;
                             
                                WAVEFORMATEX WF;
                             
                                WF.wFormatTag = WAVE_FORMAT_PCM;
                                WF.nChannels = CannalsFmt(Fmt);
                                WF.nSamplesPerSec = Rate;
                                WF.nAvgBytesPerSec = BytesFmt(Fmt)*Rate;
                                WF.nBlockAlign = BytesFmt(Fmt);
                                WF.wBitsPerSample = BitsFmt(Fmt);
                                WF.cbSize = sizeof(WF);
                             
                                int R = waveOutOpen(&WO,0,&WF,(UINT)&waveOutCallBack,(UINT)this,CALLBACK_FUNCTION);
                                assert(R==0);
                             
                                int BufSize = BytesFmt(Fmt)*Size;
                                Buf = new char [2*BufSize];
                             
                                for (int i = 0; i < BufSize; i++) {
                                    Buf[i] = random(16000);
                                }
                                for (int i = BufSize; i < 2*BufSize; i++) {
                                    Buf[i] = random(100);
                                }
                             
                                for (int i = 0; i < 2; i++)
                                {
                                    ZeroMemory(&WH[i],sizeof(WAVEHDR));
                                    WH[i].lpData = Buf + i*BufSize;
                                    WH[i].dwBufferLength = BufSize;
                             
                                    R = waveOutPrepareHeader(WO,&WH[i],sizeof(WAVEHDR));
                                    assert(R==0);
                                }
                             
                            }
                             
                            CBuffer::~CBuffer()
                            {
                                waveOutPause(WO);
                                for (int i = 0; i<2; i++)
                                {
                                  waveOutUnprepareHeader(WO,&WH[i],sizeof(WAVEHDR));
                                }
                                waveOutClose(WO);
                            }
                             
                            void CBuffer::Play(int n)
                            {
                                int R = waveOutWrite(WO, &WH[n], sizeof(WAVEHDR));
                                //if (R!=0)
                                assert((R==0)|(R==33));
                            }
                             
                            void CBuffer::Pause()
                            {
                                int R = waveOutPause(WO);
                                assert(R==0);
                            }
                             
                            void CBuffer::Restart()
                            {
                                int R = waveOutRestart(WO);
                                assert(R==0);
                            }
                             
                            void CBuffer::Reset()
                            {
                                int R = waveOutReset(WO);
                                assert(R==0);
                            }
                             
                            void CBuffer::SetVol(int aVol)
                            {
                                unsigned int V = aVol*256*256+aVol;
                                int R = waveOutSetVolume(WO,V);
                                assert(R==0);
                            }
                             
                            int CBuffer::GetBufNum(void *P)
                            {
                                  if (P==&WH[0]) return 0;
                                  if (P==&WH[1]) return 1;
                                  assert(false);
                                  return -1;
                            }
                             
                            void *CBuffer::GetBufPtr(int N)
                            {
                                return WH[N].lpData;
                                //return Buf+N*BufSize;
                            }
                             
                             
                            CPlayTh::CPlayTh(CPlayer *aPlayer):TThread(true)
                            {
                                Player = aPlayer;
                             
                                Priority = tpTimeCritical;
                             
                                SignalDone = CreateEvent(NULL,true,false,NULL);
                             
                                Resume();
                            }
                             
                            void __fastcall CPlayTh::Execute()
                            {
                                do{
                                    WaitForSingleObject(SignalDone,INFINITE);
                                    ResetEvent(SignalDone);
                             
                                    if (!Terminated)
                                        Player->LoadTh();
                             
                                }while (!Terminated);
                            }
                             
                            void CPlayTh::Done()
                            {
                                SetEvent(SignalDone);
                            }
                             
                             
                             
                            void CPlayer::LoadNextFrame(int nBuf)
                            {
                                Wav->Read( Buf->GetBufPtr(nBuf) );
                            }
                             
                            void CPlayer::DoneBuf(int n)
                            {
                                //if (n==0) {n = 1;} else n = 0;
                             
                                nBuf = n;
                             
                                bool DoneFile = Wav->GetPos() >= Wav->GetBufCount();
                             
                                if (!DoneFile)
                                    Th->Done();
                             
                                if (Wnd!=0)
                                {
                                    PostMessage(Wnd,WM_USER,PM_DONE_BUF,n);
                                    if (DoneFile)
                                        PostMessage(Wnd,WM_USER,PM_DONE_FILE,0);
                                }
                             
                            }
                             
                            void __fastcall CPlayer::LoadTh()
                            {
                                EnterCriticalSection(&CS);
                                    int Temp = nBuf;
                                    LoadNextFrame(Temp);
                                    if (Played)
                                        Buf->Play(Temp);
                                LeaveCriticalSection(&CS);
                            }
                             
                            CPlayer::CPlayer(CWAVE *aWav, HWND W)
                            {
                                Wav = aWav;
                             
                                Buf = new CBuffer(Wav->GetFmt(), Wav->GetSize(), Wav->GetRate());
                                Buf->pPlayer = this;
                             
                                InitializeCriticalSection(&CS);
                                SetPos(0);
                             
                                Th = new CPlayTh(this);
                             
                                Paused = false;
                                Played = false;
                             
                                Wnd = W;
                            }
                             
                            CPlayer::~CPlayer()
                            {
                                Th->Terminate();
                                Th->Done();
                                Th->WaitFor();
                                delete Th;
                             
                                delete Buf;
                            }
                             
                            void CPlayer::SetPos(int nPos)
                            {
                                bool Pl = (Played)&&(!Paused);
                             
                                Played = false;
                                Paused = false;
                             
                                EnterCriticalSection(&CS);
                                    Buf->Reset();
                                    Wav->SetPos(nPos);
                                    LoadNextFrame(0);
                                    LoadNextFrame(1);
                             
                                    if (Pl)
                                        Play();
                                LeaveCriticalSection(&CS);
                            }
                             
                            void CPlayer::SetVol(int aVol)
                            {
                                Buf->SetVol(aVol);
                            }
                             
                            void CPlayer::Play()
                            {
                                if (!Paused)
                                {
                                    Buf->Play(0);
                                    Buf->Play(1);
                                }else
                                    Buf->Restart();
                             
                                Paused = false;
                                Played = true;
                            }
                             
                            void CPlayer::Pause()
                            {
                                Buf->Pause();
                                Paused = true;
                            }


                          Ошибка 33 возникает при попытке сменить позицию воспроизведения у плейера, когда он воспроизодит файл.
                            В общем, что я выяснил. 33 вылезает, если попытаться впихнуть через waveoutwrite в очередь заголовок, который уже и так в очереди. Кроме того, если попытаться выполнить unprepare такого заголовка. Как бы 33 так и говорит: The data block pointed to by the pwh parameter is still in the queue("оно уже/ещё играется, чё ты хочешь?"). Так что это всё-таки ошибка(в программе), а где именно, не скажу, так как в сишной программе не ориентируюсь.
                            Сообщение отредактировано: Prince -
                              Тогда такой вопрос. Если у устройства один буфер воспроизводится, а второй находится в очереди на воспроизвидения, при сбросе устройства (waveOutReset(WO)) оба буфера будут удалены из очереди?

                              Добавлено
                              В спавке пишут что все буфера из очереди высвобождаются и помечаются как выполненые. а вот генерируется ли сообщение DONE не написано. Я исходил из того что оно при Reset не генерируется.
                                Да, все будут удалены. И да, на каждый будет сгенерировано DONE.

                                И ещё в другой теме я писал, по поводу waveinreset, на всякий пожарный:
                                Цитата
                                Кстати, столкнулся с непонятным явлением. Waveinreset выбросит из очереди все буферы и процесс записи будет остановлен. При этом поле dwBytesRecorded будет содержать фактическое количество записанной информации до того момента когда запись была прервана, или ноль, для тех буферов, которые ожидали своей очереди.
                                Так вот. Если в консольном приложении вызвать Waveinreset, то в кэлбэке при попытке расфиксировать такой буфер(wavinunprepareheader) возникает исключение. В то же время, если приложение не консольное, ничего подобного не происходит. В чем причина, пока не понял, возможно, я где-то ошибся или что-то недопонял.
                                Сообщение отредактировано: Prince -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0549 ]   [ 16 queries used ]   [ Generated: 19.03.24, 03:33 GMT ]