На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania 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
Модераторы: barazuk
  
> Создание прямоугольных импульсов разной длительности, На звуковом разьеме под WM
    Хочу сделать подобное, только на морально устаревающем смартфоне с винмобаил 6.1.
    Надо получить циклическую последовательность импульсов 1-3мС с дискретностью 0.1мС и, с возможностью независимого их изменения.
    Возможно,надо заранее создать 10 байтовых массивов и подключать нужный.Может кто подскажет, как подобное реализовать с минимальной загрузкой цпу.
    Надеюсь,сама идея кого-нибудь заинтересует, т.к. телефоны имеют камеры ,вай-фай,жпс,акселерометр, и совсей этой :) можно попытаться взлететь , ну или хотябы поползти...

    ПС В "железе" я разбираюсь чуть лучше и возможна кооперация.
    "Все говорят:"Мы в месте!"-Не многие знают в каком!"
      Цитата
      Надо получить циклическую последовательность импульсов 1-3мС с дискретностью 0.1мС

      Ничего непонятно, но не суть. Протокол обмена можно потом додумать.
      А вывод звука под винмобайл возможен при помощи всё тех же Waveform Audio Functions Во всяком случае, попробуйте. Начните с waveOutGetNumDevs и waveOutGetDevCaps.
      Или при помощи PlaySound попробуйте "побибикать" под винмобайл.
      Если фунции отработают, то и прочими из списка можно воспользоваться.
      Сообщение отредактировано: Prince -
      Человек человека понять не может.
        Цитата Prince @
        Ничего непонятно, но не суть. Протокол обмена можно потом додумать.

        Чего тут не понять? :blink: :o Стандартный модельный протокол PPM.
        Каждые 20мС передается посылка , состоящая из длинного импульса 3-4мс (маркер начала)и канальных импульсов . Длительночть последних определяет положение рулей , скорость вращения моторов...
        1,5мс -нейтраль , +- до 0,5 от нее -отклонение рулей в ту или другую сторону. как-то так.
        Я по эксперементировал тут (нашел исходник на басике c WaveOut, подрихтовал ) Результат плачевный. :'(
        Сами импульсы разной скважности получаются хорошо, но растояние между ними 40мС. :'(
        Делал я так: Создал несколько 100 байтовых массивов , забил в них 0 и 255, в нужном кол-ве и поочередно их подсовывал. Частота 44100.
        Это я чего-то не так делаю,бэйсик тормозит или виндоуз с такими маленькими буферами не работает?
        Сообщение отредактировано: Alexei -
        "Все говорят:"Мы в месте!"-Не многие знают в каком!"
          Скорее всего железка требует буфер кратный 4096 отсюда 4096/(2*44100)~46 мс. Можно в таймере попробовать писать изменения в буфере после того как отдали его на обработку, но не факт что взлетит(заработае ).
          Правильный обед должен состоять из 5 блюд приготовленных из 33 ингредиентов.
            Цитата
            Делал я так: Создал несколько 100 байтовых массивов , забил в них 0 и 255, в нужном кол-ве и поочередно их подсовывал. Частота 44100.

            Механизм подсовывания очень важен.
            Цитата
            Делал я так: Создал несколько 100 байтовых массивов , забил в них 0 и 255, в нужном кол-ве и поочередно их подсовывал. Частота 44100.

            Хотя бы 100 мс(а не байт). Тем паче, что девайс маломощный. 100 байт - это ну совсем ничего.
            Цитата
            виндоуз с такими маленькими буферами не работает?

            Винда мноозадачная, 100 байт выплюнутся за 22 мс, нужен следующий буфер, а ваше приложение в отключке, потому что процессорное время уже отдано другому процессу.
            100 мс буфер(или больше) и правильный механизм подсовывания - ключ к успеху.
            Цитата
            Чего тут не понять? Стандартный модельный протокол PPM.

            Даже если б я его знал назубок, пот такому описаниюи вряд ли бы догадался. :-?
            Человек человека понять не может.
              Цитата Prince @
              100 байт выплюнутся за 22 мс

              Я вообще то расчитывал на 2,2мС :), и осцил показывает , что так и есть.
              Цитата
              Хотя бы 100 мс

              Это невыносимо долго. :no-sad: Есть мысль удлинить до 20мС -заполнять буфер сразу всей посылкой.
              Цитата
              Механизм подсовывания очень важен.

              Через сообщение главному окну, кажется, я не сильно вникал. В оригинале эта программка делала синус и потрескивала. Думаю, из-за незаконченности синуса в буфере.
              "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                А, да, 2мс. :) Это даже не ничто, а ничего от ничто.
                Цитата
                Это невыносимо долго.

                Невыносимо долго ЧТО? Невыносимо долго для чего?
                Цитата
                Есть мысль удлинить до 20мС -заполнять буфер сразу всей посылкой.

                Интуитивно догадываюсь, что вам нужно поработать над алгоримтом формирования сигнала, он не должен в идеале зависеть от длительности буфера.
                Цитата
                Через сообщение главному окну, кажется, я не сильно вникал. В оригинале эта программка делала синус и потрескивала. Думаю, из-за незаконченности синуса в буфере.

                Не, так вы вникните, механизм подсовывания важен вообще, его реализация т.е., а не способ(окно, поток, функция) уведомления только.
                Сколько в очереди буферов крутится вообще? Сколько в очереди находятся одновременно? Как происходит заполнение буфера, кто является инициатором процесса?
                Сообщение отредактировано: Prince -
                Человек человека понять не может.
                  В идеале, картина должна бы выглядеть так:
                  в очереди крутятся 2 буфера, длительностью 20 мс каждый, равной длине посылки.
                  когда буфер освобождается, происходит опрос органов управления, заполнение пустого буфера новой посылкой и постановка его в очередь.

                  Тогда время реакции на действия пилота было бы в районе 40 мс. А опрос органов управления и формирование посылки были бы синхронизированы.
                  Но такой короткий буфер, девайс, вероятно, не потянет(но всё же попробуйте).

                  А если длительность буфера больше длительности посылки, пусть даже кратной 20 мс, придётся разделить опрос органов управления и процесс заполнения буфера и озадачиться синхронизацией очереди буферов и очереди управляющих команд. Как такой вариант реализовать, в деталях пока без понятия. Возможно, есть вариант более красивый, но с ходу его не вижу.
                  Сообщение отредактировано: Prince -
                  Человек человека понять не может.
                    Как оказалось дело не в "бабине", то есть не совсем в ней. Я сначала сделал буфер в 5000байт , и теже ~40мС остались. После чего я посмотрел работу программы этого пограмиста , там щелкают теже 40мс.
                    Так что , возможно , шансы есть.
                    Я хотел сделать так: создать 2-3 десятка 100 байтных буферов, занести в них образы импульсов разной скважности(больше- меньше разных градаций и нейтраль) , и каждый раз подсовывать нужный буфер соответствующий значению команды текущего канала.
                    Второй вариант : сделать два буфера длиною в полную посылку~20мС ,заранее заполненых нейтральными значениями, и пока один "играет" второй дописывать нужным колвом "0" или "1" в нужных местах .
                    "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                      В виндоуме работа со зауком это шаманство. Так как не отгадаешь что и как будет работать. Вот второй вариант с 2 буферами возможен. Но я бы лучше взял 3 буфера по 4096. Пока первый ишрается, третий заполняем. Второй должен быть отдаем на исполнение, до того как 1 начнёт играть. Тройной буфер нуден для того чтобы небыло барьера. Т.е. щелчков.
                      А размер должен быть кратен странице иначе поведение плохо предсказуемо. Про размер буфера насколько помню это оговарено в документации.
                      Сообщение отредактировано: Pavia -
                      Правильный обед должен состоять из 5 блюд приготовленных из 33 ингредиентов.
                        Цитата
                        лучше взял 3 буфера по 4096.

                        3 буфера будут сильно замедлять реакцию на органы управления.А щелчки , я же не слушать их буду, главное чтобы они не мешали находить среди них правльные импульсы.
                        "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                          Попробовал играть меандр на Си , получилось чуть лучше, но тоже щелкает.Два буфера по 5000 байт,пробовал увеличить в двое -без изменений.Сделал через CALLBACK_WINDOW
                          ExpandedWrap disabled
                            case MM_WOM_DONE:
                                    
                                        if (numBuff==0)
                                        {
                                            waveOutWrite(hWaveOut, &whdr1, sizeof(whdr1));
                                            numBuff=1;
                                        }
                                        else    
                                        {
                                            numBuff=0;
                                            waveOutWrite(hWaveOut, &whdr2, sizeof(whdr2));
                                        }
                                        
                                        return TRUE;

                          Может можно что-то получше?
                          И что быстрее через окно или функцию?

                          В структуре WAVEHDR есть зарезервированное lpNext , наверно указатель на структуру следуущего буфера.Думаю, это то что мне подошло БЫ. :yes-sad:

                          Посмотрел осциллом- теже 40мс между переключениями. :wall: :no-sad:
                          Сообщение отредактировано: Alexei -
                          "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                            Имхо, что-то не то или не так делаете. Выкладывайте весь кусок от waveinopen с обработкой сообщений. Код, заполняющий буфер, не нужен. Просто камент поставьте "тут записываем в такой-то буфер такие-то данные".

                            Цитата
                            Цитата
                            if (numBuff==0)
                            {
                            waveOutWrite(hWaveOut, &whdr1, sizeof(whdr1));
                            numBuff=1;
                            }

                            lParam = (LONG) lpwvhdr. Т.е., адрес заголовка и буфера у вас и так есть. numBuff не нужен, и такой способ идентификации ненадёжен.

                            Цитата
                            Посмотрел осциллом- теже 40мс между переключениями.

                            В смысле, пауза в 40 мс между окончанием одного буфера и началом следущего?
                            Создайте 5 буферов по 0.5 с, заполните их значениями непрерывной синусоиды, и поставьте в очередь.
                            Если разрывов не будет, значит вы накосячили, если разрывы останутся, значит, девайс косячит, но я в этом сомневаюсь.
                            Человек человека понять не может.
                              Цитата
                              Выкладывайте весь кусок

                              Все целиком.
                              ExpandedWrap disabled
                                #define WIN32_LEAN_AND_MEAN
                                 
                                 
                                #include <windows.h>
                                #include <windowsx.h>
                                #include <commctrl.h>
                                #include <tchar.h>
                                #include <mmsystem.h>
                                #include <stdio.h>
                                #include "main.h"
                                 
                                #pragma comment(lib, "winmm.lib")
                                 
                                #define UNICODE
                                #define NELEMS(a)  (sizeof(a) / sizeof((a)[0]))
                                #define nRate   44100
                                #define nBits   8
                                #define nBytesPerSample      nBits / 8
                                 
                                 
                                 
                                 
                                #define nBytes     10000 //
                                 
                                /** Prototypes **************************************************************/
                                 
                                static INT_PTR CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM);
                                 
                                /** Global variables ********************************************************/
                                 
                                static HANDLE ghInstance;
                                HWAVEOUT hWaveOut;
                                 
                                WAVEFORMATEX wfx; // для получения описателя звукового устройства:
                                WAVEHDR  whdr1;
                                WAVEHDR  whdr2;
                                static UCHAR    Buffer1[nBytes];
                                static UCHAR    Buffer2[nBytes];
                                UCHAR   numBuff ;
                                /****************************************************************************
                                 *                                                                          *
                                 * Function: WinMain                                                        *
                                 *                                                                          *
                                 * Purpose : Initialize the application.  Register a window class,          *
                                 *           create and display the main window and enter the               *
                                 *           message loop.                                                  *
                                 *                                                                          *
                                 * History : Date      Reason                                               *
                                 *           00/00/00  Created                                              *
                                 *                                                                          *
                                 ****************************************************************************/
                                 
                                int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
                                {
                                    INITCOMMONCONTROLSEX icc;
                                    WNDCLASSEX wcx;
                                 
                                    ghInstance = hInstance;
                                 
                                    
                                    icc.dwSize = sizeof(icc);
                                    icc.dwICC = ICC_WIN95_CLASSES /*|ICC_COOL_CLASSES|ICC_DATE_CLASSES|ICC_PAGESCROLLER_CLASS|ICC_USEREX_CLASSES|... */;
                                    InitCommonControlsEx(&icc);
                                    
                                    
                                    wcx.cbSize = sizeof(wcx);
                                    if (!GetClassInfoEx(NULL, MAKEINTRESOURCE(32770), &wcx))
                                        return 0;
                                 
                                  
                                    wcx.hInstance = hInstance;
                                    wcx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_ICO_MAIN));
                                    wcx.lpszClassName = _T("ppmClass");
                                    if (!RegisterClassEx(&wcx))
                                        return 0;
                                 
                                    /* The user interface is a modal dialog box */
                                    return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)MainDlgProc);
                                }
                                 
                                /****************************************************************************
                                 *                                                                          *
                                 * Function: MainDlgProc                                                    *
                                 *                                                                          *
                                 * Purpose : Process messages for the Main dialog.                          *
                                 *                                                                          *
                                 * History : Date      Reason                                               *
                                 *           00/00/00  Created                                              *
                                 *                                                                          *
                                 ****************************************************************************/
                                 
                                static INT_PTR CALLBACK MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                                {
                                    switch (uMsg)
                                    {
                                        case WM_INITDIALOG:
                                            /*
                                             * TODO: Add code to initialize the dialog.
                                             */
                                        for (UINT i = 0; i < nBytes; i++)
                                          {
                                             if((i/100)%2)
                                                    Buffer1[i] = 255;
                                             else
                                                    Buffer1[i] = 0;
                                         }
                                        for (UINT i = 0; i < nBytes; i++)
                                          {
                                             if((i/10)%2)
                                                    Buffer2[i] = 255;
                                             else
                                                    Buffer2[i] = 0;
                                          }
                                        wfx.wFormatTag = WAVE_FORMAT_PCM;   // wav-формат
                                        wfx.nChannels = 1; // моно - звук
                                        wfx.nSamplesPerSec = nRate; // 44100 Гц
                                        wfx.nAvgBytesPerSec = nBytesPerSample * nRate; // байт в секунду
                                        wfx.nBlockAlign = nBytesPerSample;
                                        wfx.wBitsPerSample = nBits;
                                        wfx.cbSize = 0; // For only WAVE_FORMAT_PCM formats, this member is ignored
                                 
                                        numBuff=0;
                                        
                                            return TRUE;
                                 
                                        case WM_SIZE:
                                            /*
                                             * TODO: Add code to process resizing, when needed.
                                             */
                                            return TRUE;
                                    case MM_WOM_DONE:
                                        
                                            if (numBuff==0)
                                            {
                                                waveOutWrite(hWaveOut, &whdr1, sizeof(whdr1));
                                                numBuff=1;
                                            }
                                            else    
                                            {
                                                numBuff=0;
                                                waveOutWrite(hWaveOut, &whdr2, sizeof(whdr2));
                                            }
                                            
                                        return TRUE;
                                 
                                        case WM_COMMAND:
                                            switch (GET_WM_COMMAND_ID(wParam, lParam))
                                            {
                                                /*
                                                 * TODO: Add more control ID's, when needed.
                                                 */
                                          case IDSTART:
                                                
                                            waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (UINT)hwndDlg, 0L, CALLBACK_WINDOW);
                                            whdr1.lpData = (LPSTR)Buffer1;
                                            whdr1.dwBufferLength = nBytes; // размер буфера в байтах.
                                            whdr1.dwFlags = 0; // Буфер подготовлен (зафиксирован в памяти)
                                            whdr1.dwLoops = 0; //  без циклов, поле должно быть нулевым.
                                 
                                            whdr2.lpData = (LPSTR)Buffer2;
                                            whdr2.dwBufferLength = nBytes; // размер буфера в байтах.
                                            whdr2.dwFlags = 0; // Буфер подготовлен (зафиксирован в памяти)
                                            whdr2.dwLoops = 0; //  без циклов, поле должно быть нулевым.
                                                
                                            waveOutPrepareHeader(hWaveOut, &whdr1, sizeof(WAVEHDR));
                                            waveOutPrepareHeader(hWaveOut, &whdr2, sizeof(WAVEHDR));
                                 
                                            waveOutWrite(hWaveOut, &whdr1, sizeof(whdr1));
                                                
                                        
                                          return TRUE;
                                        
                                 
                                                case IDOK:
                                                    EndDialog(hwndDlg, TRUE);
                                            
                                            waveOutUnprepareHeader (hWaveOut, &whdr1, sizeof(WAVEHDR));
                                            waveOutUnprepareHeader (hWaveOut, &whdr2, sizeof(WAVEHDR));
                                            waveOutReset (hWaveOut);
                                            waveOutClose (hWaveOut);
                                                    return TRUE;
                                            }
                                            break;
                                 
                                        case WM_CLOSE:
                                            EndDialog(hwndDlg, 0);
                                            return TRUE;
                                 
                                        /*
                                         * TODO: Add more messages, when needed.
                                         */
                                    }
                                 
                                    return FALSE;
                                }

                              Цитата
                              numBuff не нужен, и такой способ идентификации ненадёжен.

                              Это для того чтобы решить , какой буфер играть.
                              Цитата
                              В смысле, пауза в 40 мс между окончанием одного буфера и началом следущего?

                              Да.
                              Цитата
                              Создайте 5 буферов по 0.5 с

                              Не думаю, что в этом есть смысл , я нашел здесь ,неподалеку , программку на ВБ . Она прекрасно играет без разрывов. У нее два буфера по 44100(1 сек) . Я помучил ее , она не трещит, если уменьшать до 1800 байт. Кстати, это ~40мС. :)
                              "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                                Очередь буферов устроена по принципу FIFO.
                                Сначала нужно поставить в очередь все(несколько) буферы, при помощи wavoutwrite. Когда первый в очереди буфер воспроизведен, он выталкивается из очереди; начинает воспроизводиться следующий за ним, без задержки(теперь этот буфер становится первым в очереди).
                                Когда буфер вытолкнут из очереди, приложению посылается месседж MM_WOM_DONE, поле lparam которого содержит адрес заголовка буфера. А заголовок, в свою очередь, хранит адрес буфера в lpdata. Его(буфер) можно заполнить новой порцией данных и снова поставить в очередь(в конец очереди) при помощи wavoutwrite.

                                ExpandedWrap disabled
                                  case IDSTART:
                                   
                                              waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (UINT)hwndDlg, 0L, CALLBACK_WINDOW);
                                              //...
                                              waveOutPrepareHeader(hWaveOut, &whdr1, sizeof(WAVEHDR));
                                              waveOutPrepareHeader(hWaveOut, &whdr2, sizeof(WAVEHDR));
                                   
                                              waveOutWrite(hWaveOut, &whdr1, sizeof(whdr1));
                                  //сюда добавить WaveOutWrite(hWaveOut, &whdr2, sizeof(whdr2));
                                   
                                            return TRUE;


                                Цитата
                                Это для того чтобы решить , какой буфер играть.

                                См. выше. Какая-то специальная нумерация буферов не нужна(когда-то я тоже такие костыли изобретал). Точные "координаты" буфера в lparam обрабатываемого месседжа MM_WOM_DONE.
                                MM_WOM_DONE не указывает "какой буфер играть", а сообщает о том, что "такой-то буфер уже отыграл, дальше делайте с ним, что хотите".
                                WaveOutWrite не "начинает играть такой-то буфер", а ставит буфер в конец очереди [буферов]. Поставленный в очередь буфер начинает воспроизводиться сразу только в том случае, если очередь была пуста, и воспроизведение не остановлено при помощи WaveOutPause.
                                Сообщение отредактировано: Prince -
                                Человек человека понять не может.
                                  Спасибо!
                                  ExpandedWrap disabled
                                     waveOutWrite(hWaveOut, &whdr1, sizeof(whdr1));
                                    //сюда добавить WaveOutWrite(hWaveOut, &whdr2, sizeof(whdr2));

                                  Это сильно помогло! :)
                                  Цитата
                                  Очередь буферов устроена по принципу FIFO.
                                  ....
                                  WaveOutWrite не "начинает играть такой-то буфер", а ставит буфер в конец очереди

                                  А это очень интересно.
                                  "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                                    Цитата
                                    Точные "координаты" буфера в lparam обрабатываемого месседжа MM_WOM_DONE.

                                    А доставать lparam как-то заморочисто надо? Что то у меня не получается.
                                    "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                                      static INT_PTR CALLBACK MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                                      Как оно там в си может выглядеть, я не в курсе.
                                      А вообще, вытягиваение координат из lparam и доступ к элементам буфера(семплам) выглядит(может выглядеть) так:
                                      ExpandedWrap disabled
                                        var pb:pbyte:// указатель на байт, который будем использовать для доступа к содержимому буфера;
                                        //устанавливаем указатель на начало буфера(допустим, буфер 8 битный, один канал):
                                        pb:=pbyte(pwavehdr(lparam).lpdata); // приведение типов, сначала lparam к wavehdr, затем lpdata к pbyte;
                                        // дальше чё-то делаем с ним:
                                        for i:=0 to pwavehdr(lparam).dwBufferLength-1 do
                                        Begin
                                        pb:=128;// заполняем текущий семпл "тишиной"
                                        inc(pb)// переходим к следующему семплу
                                        end;
                                      Человек человека понять не может.
                                        "Семен Семеныч"(с) . Это я тормозил, надо заправлять тот же буфер который только что отыграл...
                                        ExpandedWrap disabled
                                             case MM_WOM_DONE:
                                                  waveOutWrite(hWaveOut,(PWAVEHDR) lParam, sizeof(WAVEHDR));
                                        "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                                          И предварительно заправлять несколько буферов в очередь. И позаботиться о том, чтобы после отыгрывания буфера, он был возвращен в очередь до того, как отыграет следующий за ним. Этот пункт накладывает ограничения на минимальный размер буфера.
                                          Цитата
                                          я нашел здесь ,неподалеку , программку на ВБ . Она прекрасно играет без разрывов. У нее два буфера по 44100(1 сек) . Я помучил ее , она не трещит, если уменьшать до 1800 байт. Кстати, это ~40мС

                                          Постепенно уменьшая размер буфера, всё больше и больше нагружаем проц и систему, сообщения MM_WOM_DONE сыпятся всё чаще и чаще. Уменьшаем, уменьшаем дальше, и опа, в какой-то момент, приложение не успевает обработать очередной MM_WOM_DONE, и добавить новый буфер в очередь до окончания воспроизведения текущего. Звук рвётся. Этот момент(и минимальный размер буфера, при котором разрывов не будет) зависит от кванта времени, выделяемого приложению виндой, производительности системы и загруженности её работающими параллельно другими процессами.
                                          Почему я говорил про 100 мс. С буфером такой длительности приложение в штатной ситуации никогда не порвёт звук и не сильно нагружает систему. На "больших" компах.
                                          Человек человека понять не может.
                                            Снова реанимировался вопрос про то , как узнать какой буфер только что отыграл.
                                            Цитата
                                            Параметр lParam содержит адрес структуры WAVEHDR, соответствующей проигранному блоку.
                                            Это из интернета.
                                            Действительно содержит, только есть небольшое отличие с тем что я отправляю.
                                            Вскрытие показало, что у обоих младшие 64р-да совпадают, но у lParam старшие 64 равны 0, а у адреса отправленной структуры в младшем -1. Можно ее , конечно, придушить, но...
                                            "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                                              В винмобайл? Вот прям 64 бита? Да ещё и старшие/младшие?
                                              Цитата
                                              младшие 64р-да совпадают, но у lParam старшие 64 равны 0, а у адреса отправленной структуры в младшем -1.

                                              Ничего непонятно.
                                              Человек человека понять не может.
                                                Цитата Prince @
                                                В винмобайл?

                                                Нет. 8.1 (64)
                                                "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                                                  Цитата
                                                  младшие 64р-да совпадают, но у lParam старшие 64 равны 0, а у адреса отправленной структуры в младшем -1.

                                                  Осталось эту странную лексическую конструкцию осилить.
                                                  Человек человека понять не может.
                                                    Не надо ее осиливать, это какие-то проблемы с 64.
                                                    А у меня проблема я не знаю как сравнить :
                                                    lParam с &whdr(структура WAVEHDR)
                                                    Ругается, что я сравниваю не то не с тем. :)
                                                    "Все говорят:"Мы в месте!"-Не многие знают в каком!"
                                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                    0 пользователей:


                                                    Рейтинг@Mail.ru
                                                    [ Script Execution time: 0,2032 ]   [ 17 queries used ]   [ Generated: 22.09.17, 13:25 GMT ]