Здравствуйте дорогие форумчане! С целью оптимизации своей программы написанной на VB6 я делаю DLL для работы со звуковыми данными. Собственно у меня вот в чем загвоздка: звуковые Wave данные бывают разных форматов, т.е. с разной частотой дискретизации, с разным количеством каналов и разрядностью. Я в свою DLL вставил процедуру которая конвертирует данные в один общий формат, (который также задается вызовом функции из этой DLL),и у меня возникла проблема преобразования размера данных(например из 16->8 бит на выборку). Как можно более грамонтно сделать это преобразование? Я сейчас использую следующий алгоритм (код весь выкладывать на буду очень много, приведу только алгоритм): Код (Text): WAVEFORMAT Struct wFormatTag dw ? nBitPerSample dw ? nChannels As dw ? nSamplesPerSec As dd ? nAvgBytesPerSec As dd ? nBlockAlign As dw ? WAVEFORMAT ends Convert proc USES edi esi FDATS:DWORD,FLEN:DWORD,FROMFORMAT:DWORD,TDATS:DWORD FDATS- исходные данные FLEN- Размер конечных данных в байтах FROMFORMAT-Исходный формат(указатель на WaveFormat) TDATS-Указатель на приемник преобразованных данных 1. Сначала узнаем nSamplesPerSec источника(sCnt) и приемника(dCnt) в байтах 2. Вычисляем маску для источника(sMask). Например у меня исходный nBitPerSample=16 значит маска будет 0FFFFh 3. Находим отношение nSamplesPerSec источника на nSamplesPerSecond приемника: Temp=0 4. В CX помещаем разность Источникого nBitPerSample-Приемникого nBitPerSample 5. Цикл прохода по байтам источнка:(ebx=FLEN,esi=TDATS,edi=FDATS) mov eax,Temp ; Поместить указатель источника mul sCnt add eax,FDATS mov edi,eax mov eax,[edi] ; Загрузить DW источника в EAX and eax,sMask ; Выделить нужные биты sal eax,cl ; Преобразовать в BITPERSAMPLE mov [esi],eax ; Загрузить в TDATS add esi,dCnt ; Увеличиваем указатель приемника FADD ST,ST(1) ; Увеличиваем указатель источника FIST Temp ; Сохранить в память dec ebx jz ExitConvert 6. Выход из процедуры Мне кажется что это, мягко говоря, кривой код. Может кто знает алгоритм, или API какая есть чтобы переводить звуковые данные в любой формат? Буду очень благодарен P.S. За оформление прошу сильно не пинать
rmka Это понятно я в CX заношу разность и получаю сдвиг на столко на сколько нужно. Вопрос в чем, как можно выбрать вроизвольные данные, т.е. байт, слово, двойное слово от условия. В моем алгоритме берется двойное слово и к нему применяется маска, которая и дает нужный результат.Я думаю может самомодифицирующийся код использовать, чтобы уже от условия брался нужный размер данных
Зачем вам маска и разность? Множите на BitPerSampleDest/BitPerSampleSrс или делите на BitPerSampleSrc/BitPerSampleDst, в зависимости от того что больше. Ну а выборку делаете по кол-ву байт на душу населения. И ещё желательно округлять в две стороны.
Выборку можно делать через память. Выделяете 2 четырёхбайтовых ячейки, одна для src, другая для dst. Пишите в src столько байт сколько нужно, в остаток ячейки нули. Потом читаете эту ячейку в регистр, производите операцию, пишите в dst и снова по байту записываете в выходной поток из dst. Можно конечно заморочиться и маской, но это всё оптимизации, когда уже всё будет работать.
Проблема возникает при записи последней ячейки, она выходит за пределы массива если nBitPerSampleDst<32