Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

DirectSound. Проблема с записью длительного звукового потока . [D6, D7, WinXP]


Страницы:   1 2

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 и наоборот
И как же так их синхронизировать, чтоб ни одного "бита" даннх не потерять


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо