На главную Наши проекты:
Журнал   ·   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
  
> Колбек функция записи звука - как работает?
    В программе Как программа записи звука с микрофона прерывает запись? формируются буферы
    ExpandedWrap disabled
        for(int j = jmin; j < nKan; j++)
        {
          wvRes = waveInOpen(&hwvInDev, nDev, &wvFormat, (DWORD)wvRecCallBack, 0L, CALLBACK_FUNCTION);
          wvErrorMes("\nУстройство для записи открыть не удалось!\n", wvRes);
          for(UINT i = 0; i < numBuf; i++)
          {
            char    *sbuf            = (char*)    malloc(numBufSize);
            WAVEHDR *wvBuf           = (WAVEHDR *)malloc(sizeof(*wvBuf));
            wvBuf -> lpData          = sbuf;
            wvBuf -> dwFlags         = 0;
            wvBuf -> dwLoops         = 0;
            wvBuf -> dwUser          = 0;
            wvBuf -> dwBufferLength  = numBufSize;
            wvRes =  waveInPrepareHeader(hwvInDev, wvBuf, sizeof(*wvBuf));
            wvErrorMes("\nНе удалось подготовить буфер для записи!\n", wvRes);
            wvRes =  waveInAddBuffer(hwvInDev, wvBuf, sizeof(*wvBuf));
            wvErrorMes("\nНе удалось добавить буфер для записи!\n", wvRes);
          }
          wvRes = waveInStart(hwvInDev);  
          wvErrorMes("\nНе удалось начать запись!\n", wvRes);
        }
    и используется колбек функция:
    ExpandedWrap disabled
      void CALLBACK wvRecCallBack(HWAVEIN hwvInDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
      {
        WAVEHDR *wvBuf = (WAVEHDR*) dwParam1;  
        MMRESULT wvRes = 0;
        switch(uMsg)
        {
          case WIM_OPEN:
            printf("\nЗапись началась\n");
            break;
          case WIM_DATA:
            if(!mode)
              printf("Операции с буфером\n");
            fwrite(wvBuf -> lpData, wvBuf -> dwBytesRecorded, 1, pf);
            if(mode == stop)
            {
              cout << "Операции завершения записи" << endl;
              wvRes = waveInUnprepareHeader(hwvInDev, wvBuf, sizeof(*wvBuf));
              wvErrorMes("\nНе удалось освободить буфер!\n", wvRes);          
              free(wvBuf -> lpData);
              free((WAVEHDR*)dwParam1);
              numBufCyr--;
            }  
            else
            {  
            wvRes =  waveInAddBuffer(hwvInDev, wvBuf, sizeof(*wvBuf));
            wvErrorMes("\nНе удалось добавить буфер для записи!\n", wvRes);          
            }
            break;
          case WIM_CLOSE:
            printf("\nЗапись закончилась\n");
            break;
        }
      }
    Возникли следующие вопросы:
    1. Буферы сформированы, колбек функция задана. Что значит и зачем строка:
    ExpandedWrap disabled
      WAVEHDR *wvBuf = (WAVEHDR*) dwParam1;
    Она передает сформированные буферы в колбек функцию? Как колбек функция определяет, что выделенные в программе буферы должны быть переданы через dwParam1?
    2. Допустим, я хочу передать в колбек функцию целое число через dwParam2. Как это сделать? Ведь нигде в программе я не задаю, что dwParam1 связано с буферами, как колбек функция определит, с каким числом связан dwParam2?
      https://msdn.microsoft.com/en-us/library/wi...9(v=vs.85).aspx
      Приложение передаёт звуковой подсистеме буферы посредством waveinaddbuffer. После заполнения буфера, звуковая подсистема выбрасывает его из своей очереди записи и уведомляет приложение о том, что буфер заполнен. В данном случае, посредством вызова функции, куда в качестве dwParam1 передает адрес заголовка, приведенный к DWORD.
      Цитата
      Ведь нигде в программе я не задаю, что dwParam1 связано с буферами

      Майкрософт задаёт.

      Цитата
      Что значит и зачем строка:

      WAVEHDR *wvBuf = (WAVEHDR*) dwParam1;

      Присвоение значения dwParam1 локальной переменной wvBuf с одновременным приведением типа DWORD к указателю на WAVEHDR. Зачем? Чтобы можно было обратиться к полям заголовка.
      Цитата
      Допустим, я хочу передать в колбек функцию целое число через dwParam2. Как это сделать?

      Никак.
      Можете передать dwInstance в waveinopen. Это значение будет передано в колбек в одноименном параметре.
      Или использовать поле dwUser заголовка буфера.
      Сообщение отредактировано: Prince -
        Цитата Prince @
        Цитата
        Допустим, я хочу передать в колбек функцию целое число через dwParam2. Как это сделать?

        Никак.
        Можете передать dwInstance в waveinopen. Это значение будет передано в колбек в одноименном параметре.
        Или использовать поле dwUser заголовка буфера.

        А как это сделать? Ведь dwInstance в waveinopen нет.
          MMRESULT waveInOpen(
          LPHWAVEIN phwi,
          UINT uDeviceID,
          LPCWAVEFORMATEX pwfx,
          DWORD_PTR dwCallback,
          DWORD_PTR dwCallbackInstance,
          DWORD fdwOpen
          );
          Сообщение отредактировано: Prince -
            Спасибо большое, понял.
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0306 ]   [ 15 queries used ]   [ Generated: 19.03.24, 09:29 GMT ]