exp |
Отправлено: 04.11.2005, 12:34 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
В прикрепленной схеме ( ) ) то, что мне надо сделать:
Коменты к схеме:
Черный квадрат изображает 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].
|
|
Konstantine |
Отправлено: 07.11.2005, 11:46 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
ИМХО поток должен выставлять флаги заполнения буферов а основной поток — проверять их... или в цикле или даже по таймеру (причём период таймер=[время воспр. буфера]/2 или даже на 3)
а кто заполняет буфер? осн. поток "подсовывает" дополнительному?
щас код почитаю (если разберусь )
|
|
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), то никаких проблем не будет...
|
|