![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
DirectSound. Проблема с записью длительного звукового потока . [D6, D7, WinXP]
MACTEP'oK © (2005-05-22 13:45:00)Почему при извлечении данных из буффера захвата (Lock -> UnLock) запись в буффер не происходит (тока позиция курсора записи изменяется). Это сильно заметно, если извлекать данные слишком часто (в меньшем объеме). Поскольку я записываю длительный звуковой поток действия извлечения и записи данных должны происходить одновременно. Но при этом я теряю данные которые должны были быть записаны в промежуток времени (Lock -> UnLock). Кроме того на этом участке остаются старые записанные данные, что вызывает крихтение и дребезжание.
Уважаемые мастера помогите решить эту задачу: Как записать длительный звуковой поток без потери данных?
MACTEP'oK (2005-05-25 15:58:00) [1]Она не может тормозить систему по следующим причинам:
1) Копируемых данных совсем немного.(~11000 Байт)
2) Такую системы как у меня даже мелкий софт не не смогёт затормозить.
Мне кажется, что DSound не хотит одновременно писать и читать из буфера, не смотря на то, что пишет и читает он из разных частей буфера. Х. знат чо.
XProger (2005-05-24 15:07:00) [2]"как такая функция может препятствовать процессу записи"
Тормозить всю систему из-за большого кол-ва копируемых данных ;)
MACTEP'oK (2005-05-24 09:09:00) [3]Я ещё раз всё проверил, оказывается всё дело не в функциях Lock, UnLock, их вообще можно запускать только один раз чоб узнать pointer буфера в ОЗУ. Запись прекращается на время вызова процедуры( моей) извлечения данных, но там нет ничего особенного кроме функции move, но как такая функция может препятствовать процессу записи:
вот процедура Move
procedure Move( const Source; var Dest; count : Integer );
{$IFDEF PUREPASCAL}
var
S, D: PChar;
I: Integer;
begin
S := PChar(@Source);
D := PChar(@Dest);
if S = D then Exit;
if Cardinal(D) > Cardinal(S) then
for I := count-1 downto 0 do
D[I] := S[I]
else
for I := 0 to count-1 do
D[I] := S[I];
end;
{$ELSE}
asm
{ ->EAX Pointer to source }
{ EDX Pointer to destination }
{ ECX Count }
PUSH ESI
PUSH EDI
MOV ESI,EAX
MOV EDI,EDX
MOV EAX,ECX
CMP EDI,ESI
JA @@down
JE @@exit
SAR ECX,2 { copy count DIV 4 dwords }
JS @@exit
REP MOVSD
MOV ECX,EAX
AND ECX,03H
REP MOVSB { copy count MOD 4 bytes }
JMP @@exit
@@down:
LEA ESI,[ESI+ECX-4] { point ESI to last dword of source }
LEA EDI,[EDI+ECX-4] { point EDI to last dword of dest }
SAR ECX,2 { copy count DIV 4 dwords }
JS @@exit
STD
REP MOVSD
MOV ECX,EAX
AND ECX,03H { copy count MOD 4 bytes }
ADD ESI,4-1 { point to last byte of rest }
ADD EDI,4-1
REP MOVSB
CLD
@@exit:
POP EDI
POP ESI
end;
{$ENDIF}
XProger (2005-05-22 22:58:00) [4]У тебя время доступа к буфферу свыше 0.5 мс? Иначе нормальный человек ничерта не заметит...
MACTEP'oK (2005-05-22 21:53:00) [5]>>XProger © (22.05.05 18:46) [14]
Нет я правильно понял: ты явно намекаешь на то, что мой буфер находится в памяти адаптера, и по этому при извлечении данных "подсистема вынуждена создавать временный буфер в основной памяти". А я говорю, что мой буфер находится в ОЗУ и....вообще скорость доступа тут не при чем. DirectSound просто обязан продолжать запись даже когда я читаю данные из участка буфера не пересекающегося с текущим участком записи. Но DirectSound в этот самый участок ничо не пишет. Тут уже встаёт вопрос: а использовать ли вообще для записи звука DirectSound, есть и другие средства.
XProger (2005-05-22 21:23:00) [6]Ты снова меня понимать не хочешь...
MACTEP'oK (2005-05-22 21:19:00) [7]Буфер захвата является первичным, а вторичные создавать нельзя.
Со вторичными буферами таких проблем не было.
Буфер захвата хоть и является первичным, но нигде не сказано, что он должен располагаться исключительно в памяти адаптера.
MACTEP'oK (2005-05-22 21:01:00) [8]>>XProger © (22.05.05 18:46) [14]
Но ведь у меня не аппаратный буфер, и расположен он в ОЗУ
XProger (2005-05-22 18:46:00) [9]"подсистема вынуждена создавать временный буфер в основной памяти"
От размера буфера скорость выделения памати под него не зависит? ;)
MACTEP'oK (2005-05-22 17:18:00) [10]вот:
"Метод открывает процедуру обновления данных в буфере. Не гарантируется, что возвращенные указатели будут ссылаться внутрь самого буфера и предоставленный участок памяти будет содержать какие-либо звуковые данные. При запросе обновления программного буфера метод действительно возвращает указатели на его участки, однако при работе с аппаратным буфером, размещенным в памяти адаптера, к которой нет прямого доступа со стороны процессора, подсистема вынуждена создавать временный буфер в основной памяти, указатели на который и возвращаются методом.
При успешном завершении метода приложению необходимо в кратчайший срок занести в предоставленные участки буфера нужные звуковые данные, после чего вызвать метод Unlock, который завершает процедуру обновления и, если данные были записаны во временный буфер, - пересылает их в память адаптера. Недостаточно быстрое заполнение буфера может привести к его опустошению и сбоям в звучании"
MACTEP'oK (2005-05-22 17:17:00) [11]>>XProger © (22.05.05 16:37) [8]
Такая зависимость будет наблюдаться если буфер расоложен в памяти адаптера:
http://www.compdoc.ru/prog/cpp/directs/
->Программирование в DirectSound
->Интерфейс IDirectSoundBuffer
->Lock - запрос обновления данных в буфере
(последний абзац)
MACTEP'oK (2005-05-22 17:14:00) [12]>>XProger © (22.05.05 16:37) [8]
Интересно почему же должно зависеть
XProger (2005-05-22 17:06:00) [13]Ты меня не понял...
MACTEP'oK (2005-05-22 16:46:00) [14]>>XProger © (22.05.05 16:37) [8]
move(pointer1,pointer2,DATASize);
и
for n:=0 to 100000 do
move(pointer(Cardinal(pointer1)+n),pointer(Cardinal(pointer1)+n),DATASize/100000);
чо быстрее
XProger (2005-05-22 16:37:00) [15]MACTEP'oK, а разве от размера буфера не зависит время доступа к нему при локании? ;)
MACTEP'oK (2005-05-22 15:45:00) [16]>>XProger © (22.05.05 15:27) [6]
есть более эффективный способ: не уменьшать, а увеличить размер обновляемого(чтение буффера) участка - треска не будет. Но записаны будут всё равно не все данные, хоть и недозаписаных данных будет меньше. А в твоём случае ничего не получится - треск останется, и потеряных данных будет больше, да ещё и разбросаны они будут по всему буфферу.
А моя задача - записать звуковые данные любого формата Без Потерь.
XProger (2005-05-22 15:27:00) [17]MACTEP'oK, попробуй обходиться более мелким буфером под данные, тем самым участив (Lock -> UnLock) :)
Если будет слышен треск или что-то в этом роде попробуй изменить формат данных (в худшую сторону для качества)
MACTEP'oK (2005-05-22 14:53:00) [18]Да! Самое главное! Из документации:
"Для каждого устройства воспроизведения можно создать не более одного буффера захвата"
http://www.compdoc.ru/prog/cpp/directs/
->Программирование в DirectSound
->Интерфейс IDirectSoundCaptureBuffer
MACTEP'oK (2005-05-22 14:43:00) [19]>>XProger © (22.05.05 14:25) [2]
>>Ах да...
>>Не пробовал поочерёдно менять буфера?
>>т.е. в этот пишется с этого считывается, потом swap и наоборот
(функции запуска и извлечения позиции записи занимают кое-какое время, за это время можно чтото потерять) Я бы хотел создать чо нибудь идеальное.
MACTEP'oK (2005-05-22 14:38:00) [20]>>XProger © (22.05.05 14:21) [1]
>>2) Чисти тот временный буффер перед записью нового куска
Зачем пустота мне тоже не нужна
>>XProger © (22.05.05 14:25) [2]
>>Ах да...
>>Не пробовал поочерёдно менять буфера?
>>т.е. в этот пишется с этого считывается, потом swap и наоборот
И как же так их синхронизировать, чтоб ни одного "бита" даннх не потерять