C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Потоки, Как узнать, что в потоке произошло?
exp
Отправлено: 04.11.2005, 12:34


Мастер участка

Группа: Участник
Сообщений: 304



В прикрепленной схеме ( smile.gif) ) то, что мне надо сделать:

Коменты к схеме:
Черный квадрат изображает Unit1. Он реализует генератор сигнала в 2-х каналах (по сути — 2 массива short int).
Окружность символизирует Поток. У потока имеется 2 "окна" (c1 и c2) для связи с внешним миром и функция, которая записывает туда сгенерированные в Unit1 значения. Внутри потока производится двойная буферизация : пока buf1 проигрывается buf2 должен заполняться.
Зеленая стрелка внутри потока символизирует цикл потока в котором происходит воспроизведение сигнала.
В месте "красный крестик" активный буфер воспроизводится звуковой . Это значит, что в это же время должен быть заполнен неактивный буфер.
Так как сигнал воспринимается потоком не непрерывно, а по кускам (по-буферно), то Unit1 должен знать (в месте "синий квадрат"), когда именно надо генерировать сигнал и отправлять его в c1 и с2 Потока, и ничего не посылать, если буфер еще не проигрался.

Т. е. как покрасивее синхронизировать событие внутри потока с событием в Unit1?
Схема:


Присоединить изображение

Присоединить изображение

Sanya
Отправлено: 04.11.2005, 13:24


Не зарегистрирован







Пропробуй использовать Событийную синзронизацию Мютексная у тебя скорей всего не прокатит.
Создаешь его с помощъю CreateEvent и тамже задаешь начальное состояние события. В потоке устанавливаешь событие в сигнальное состояния SetEvent. А с помощью WaitForSingleObject ожидаешь возникновения события в основним потоке. Периодически прерываясь для прорисовки. Или все можно перестроить на оборот.
А какой ты тоток используешь? Thread?
Doga
Отправлено: 04.11.2005, 14:55


Мастер участка

Группа: Участник
Сообщений: 575



Я бы сделал бы список-очередь буферов. Unit1 добавляла бы очередной буфер в конец этого списка, а поток воспроизведения проигрывал бы всегда первый буфер и после проигрывания сразу бы его очищал бы и удалял из списка. А затем снова начинал бы проигрывание первого по списку. Если список пустой, поток просто ждал бы новой партии буферов.

Отредактировано Doga — 04/11/2005, 14:55
exp
Отправлено: 04.11.2005, 18:56


Мастер участка

Группа: Участник
Сообщений: 304



2Sanya:
Да Thread.
Я пока сделал временную версию с генерацией сигнала внутри потока. А вот во второй версии......

2Doqa: Вариант неплох, если скорость считывания очередного буфера равна скорости его проигрывания. В противном случае очевидны проблемы: или накапливание буферов в памяти, или прерывания в звукеовом потоке.
//------------------------------------

Теперь более весела проблема: Звук идет. почему-то прерываясь.
Я с 11:00 с этим парюсь и к 19:00 уже успел сойти с ума.
Я прицепил к сообщению архив. в нем код моей проги и делфийский код проги-прототипа, найденой на необъятных просторах интернета.
Кто подскажет, где собака порылась, и почему у меня в отличие от прототипа звук идет кусками — ставлю [Beer].

User Attached Image Скачать файл
Archive.zip


Konstantine
Отправлено: 07.11.2005, 11:46


Мастер участка

Группа: Модератор
Сообщений: 545



ИМХО поток должен выставлять флаги заполнения буферов а основной поток — проверять их... или в цикле или даже по таймеру (причём период таймер=[время воспр. буфера]/2 или даже на 3)

а кто заполняет буфер? осн. поток "подсовывает" дополнительному?
щас код почитаю (если разберусь smile.gif)
exp
Отправлено: 07.11.2005, 23:09


Мастер участка

Группа: Участник
Сообщений: 304



2Konstantine
Сейчас буфер заполняется внутри потока, что в общем случае неприемлимо. Хочется освободить аудиопоток от генерации сигнала.

Меня сейчас другой вопрос : Какого вездерастущего растения воспроизведение сигнала прекращается?!
Sanya
Отправлено: 08.11.2005, 10:26


Не зарегистрирован







Если использушь Thread, то все намного проще. Из потока можно вызвать ф-ю доступа к интефейсу Synchronize(здесь твоя ф-я); там все и зделаешь через глобальные переменные. С исходниками извени нет времени разбираться.
exp
Отправлено: 09.11.2005, 23:11


Мастер участка

Группа: Участник
Сообщений: 304



Та с Синхронайзом и с внешними-то все понятно. Хотелось сделать, что-то на подобие события:
Потоку приспичило наполнить буфер — он говорить: "ХОЧУ"  — и ему наполняют буфер. Вот. Ну да ладно. Пока не это волнует....
Konstantine
Отправлено: 10.11.2005, 12:28


Мастер участка

Группа: Модератор
Сообщений: 545



так вот пока поток востпроизводит один буфер, осн. программа должна подсунуть ей другой... и выставить флаг что так и так — буфер 2 полон... и ждать пока поток выставит флаг "буфер 1 пуст"
соответственно поток должен воспроизвести буфер и выставить флаг пустоты, и затем, если второй буфер полон — востроизводить его....

если это будет сделано НЕ через VCL (буферы типа char[] или short[] или int[] и флаги — bool), то никаких проблем не будет...

Вернуться в Вопросы программирования в C++Builder