Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблема с WaitForSingleEvent / 12 сообщений из 12, страница 1 из 1
27.12.2005, 10:25
    #33458775
KALAKOM
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
Здравствуйте.

В системе есть две звуковые платы, на каждой плате по два канала воспроизведения, а также по два канала записи(Line In).
Для записи и для воспроизведение в программе выделено по потоку, т.е. для воспроизведения отдельный поток и для записи отделный поток. Эти потоки работают одновременно. Рассмотрим поток воспроизведения. В потоке воспроизведения на каждую звуковую карту выделяются два буфера исходя из той идеи, что пока воспроизводиться один буфер, второй в это время подготавливается данными и соответственно, пока второй воспроизводиться, первый подготавливается данными. Допустим, что первый буфер для первой звуковой карты мы будем называть П1, второй буфер для первой звуковой карты (П2), первый буфер для второй звуковой карты В1, а второй буфер для второй звуковой карты В2. Вот пример кода:


// Делаем события обеих карт "свободными",
// т.к. после WaveOutOpen они будут в состоянии "занято"
ResetEvent(1); // Делаем событие для первой карты "свободным"
ResetEvent(2); // Делаем событие для второй карты "свободным"

// Расчитываем данные для первого буфера первой звуковой карты (П1)
// и для первого буфера второй звуковой карты (В1)
Calc(1);

WaveOutWrite(1, ...); // Отправляем первый буфер для первой звуковой карты (П1)
WaveOutWrite(2, ...); // Отправляем первый буфер для второй звуковой карты (В1)

// Расчитываем данные для второго буфера первой звуковой карты (П2)
// и для второго буфера второй звуковой карты (В2)
Calc(2);

WaveOutWrite(1, ...); // Отправляем второй буфер для первой звуковой карты (П2)
WaveOutWrite(2, ...); // Отправляем второй буфер для второй звуковой карты (В2)

while (TRUE)
{
WaitForSingleObject(1); // Ожидаем когда закончит воспроизводиться первый буфер для первой звуковой карты (П1)
WaitForSingleObject(2); // Ожидаем когда закончит воспроизводиться первый буфер для второй звуковой карты (В1)

// Расчитываем данные для первого буфера первой звуковой карты (П1)
// и для первого буфера второй звуковой карты (В1)
Calc(1);

WaveOutWrite(1, ...); // Отправляем первый буфер для первой звуковой карты (П1)
WaveOutWrite(2, ...); // Отправляем первый буфер для второй звуковой карты (В1)

WaitForSingleObject(1); // Ожидаем когда закончит воспроизводиться второй буфер для первой звуковой карты (П2)
WaitForSingleObject(2); // Ожидаем когда закончит воспроизводиться второй буфер для второй звуковой карты (В2)

// Расчитываем данные для второго буфера первой звуковой карты (П2)
// и для второго буфера второй звуковой карты (В2)
Calc(2);

WaveOutWrite(1, ...); // Отправляем второй буфер для первой звуковой карты (П2)
WaveOutWrite(2, ...); // Отправляем второй буфер для второй звуковой карты (В2)
}

Функция Calc(int) сделана так, что по данным второй буфер является продолжением первого и соответственно первый продолжением второго, так что по данным переходы из буфера в буфер плавный.

Если подключить осциллограф к какому-нибудь каналу, то можно увидеть, что между сигналами есть паузы. Если убрать WaitForSingleObject(1, ...); // Ожидаем когда закончит воспроизводиться второй буфер для первой звуковой карты (П2)
WaitForSingleObject(2, ...); // Ожидаем когда закончит воспроизводиться второй буфер для второй звуковой карты (В2) из цикла, то можно увидеть, что буфера накладываются друг на друга. Отсюда всевозможные щелчки ну и т.д.

Такое впечатление, что функция WaitForSingleObject(1, ...) не выполняет то для чего она предназначена, а именно оповещение программы оо окончании проигрывания буфера.

Вопрос: Как это все вылечить?

Размер буфера 64Кб, частота дискретизации 44100Гц, размер сэмпла 16 бит, сигнал стерео.

Спасибо.
...
Рейтинг: 0 / 0
27.12.2005, 11:22
    #33458967
_Балтика
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
Непонятно, где запускаютя потоки и вызываются SetEvent?
...
Рейтинг: 0 / 0
27.12.2005, 12:37
    #33459208
KALAKOM
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
Все делается до начала цикла. Только объекты событий создаются через CreateEvent();
...
Рейтинг: 0 / 0
27.12.2005, 12:47
    #33459267
KALAKOM
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
Никаких SetEvent я не использую
...
Рейтинг: 0 / 0
27.12.2005, 13:03
    #33459334
_Балтика
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
Как же так? Ведь WaitForSingleObject как раз и ждут, когда событие будет установлено вызовом SetEvent
...
Рейтинг: 0 / 0
27.12.2005, 13:29
    #33459421
KALAKOM
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
А разве оно автоматически не устанавливается функцией WaveOutWrite();
...
Рейтинг: 0 / 0
27.12.2005, 13:40
    #33459459
_Балтика
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
KALAKOMА разве оно автоматически не устанавливается функцией WaveOutWrite();
Я не знаю, что это за функция.
Судя по логике она должна запускать какой-то поток, который и пишет данные в буфер (или устанавливать некоторое событие, котрое будит уже существующий поток). Этот поток, по завершении записи и должен устанавливать события, которые ожидаются в WaitForSingleObject
...
Рейтинг: 0 / 0
27.12.2005, 13:56
    #33459513
KALAKO
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
Это же вопрос я задал на другом форуме, вот что пишут по этому поводу

http://forum.sources.ru/index.php?showtopic=127166
...
Рейтинг: 0 / 0
27.12.2005, 14:44
    #33459669
_Балтика
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
Понятно.
В общем то алгоритм, предложенный Вами вполне приемлемый (хотя я бы сделал по-другому :)). Вопрос в том как должны работать функции WaveOutWrite и Calc. Я бы реализовал их как поточные функции примерно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
unsigned __stdcall WaveOutWrite(void* pArg)
{
    .........................................
    ::SetEvent(hEndWaveOutWriteEvent< 1  or  2  (передается в pArg)>)
}
unsigned __stdcall Calc(void* pArg)
{
    .........................................
}
Далее схема такая
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
HANDLE hWaveOutWriteThread1, hWaveOutWriteThread2;
HANDLE& hWaveOutWriteThreads[ 2 ] = {hWaveOutWriteThread1, hWaveOutWriteThread2};
Calc( 1 ...); 
Calc( 2 ...);
while (TRUE)
{
     hWaveOutWriteThread1 = _beginthreadex(WaveOutWrite,  0 , &[инициализационная структура],...
     hWaveOutWriteThread2 = _beginthreadex(WaveOutWrite,  0 , &[инициализационная структура],...
     WaitForMultipleObjects( 2 , hWaveOutWriteThreads, TRUE,  5000 );
     beginthreadex(Calc,  0 , &[инициализационная структура],...

     hWaveOutWriteThread1 = _beginthreadex(WaveOutWrite,  0 , &[инициализационная структура],...
     hWaveOutWriteThread2 = _beginthreadex(WaveOutWrite,  0 , &[инициализационная структура],...
     WaitForMultipleObjects( 2 , hWaveOutWriteThreads, TRUE,  5000 );
     beginthreadex(Calc,  0 , &[инициализационная структура],... 
}
Номер буфер который нужно воспроизвотить, как и номер карточки передаются в инициализационной структуре.
(Вместо библиотечной ф-ции beginthreadex можно юзать и апишную CreateThread, если не используются другие библиотечные функции)
...
Рейтинг: 0 / 0
27.12.2005, 15:46
    #33459881
KALAKOM
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
Спасибо за ответ.

Буду пробовать.
...
Рейтинг: 0 / 0
27.12.2005, 15:49
    #33459891
_Балтика
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
:) Да SetEvent теперь в
Код: plaintext
1.
2.
3.
4.
unsigned __stdcall WaveOutWrite(void* pArg)
{
    .........................................
    ::SetEvent(hEndWaveOutWriteEvent< 1  or  2  (передается в pArg)>)
}
не нужен, как и события вообще. Ожидаем только потоки.
...
Рейтинг: 0 / 0
27.12.2005, 15:51
    #33459895
_Балтика
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с WaitForSingleEvent
_Балтика:) Да SetEvent теперь в
Код: plaintext
1.
2.
3.
4.
unsigned __stdcall WaveOutWrite(void* pArg)
{
    .........................................
    ::SetEvent(hEndWaveOutWriteEvent< 1  or  2  (передается в pArg)>)
}
не нужен, как и события вообще. Ожидаем только потоки.
Осталось от первоначального варианта :)
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблема с WaitForSingleEvent / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]