Леонид, спасибо - буду разбираться..
------------ Дoбавленo:
пристрелочные испытания выявили много вопросов
по IC "RecordData":
1. точка 'doStart=Начало записи/воспроизведения' - как управлять режимом 'запись' или 'воспроизведение'? Если они следуют друг за другом, можно ли это исправить?
2. точка 'doMsgRec=Получение сообщения о заполнении буфера записи' - это отключение/включение указанного события или принудительная его выдача?
3. точка 'doMsgPlay=Сообщение о проигрывании буфера PLAY' - вопрос тот же..
4. точка 'BuffSize' - есть ли границы для значения?
5. точка 'Handle' - как его использовать?
6. точка 'onBuff2' - что и в каких случаях происходит?
7. точка 'onStream' - что в этом потоке и как его использовать?
по IC "FFT_IFFT":
1. у точек 'doSpecL=Анализатор спектра левый' и 'doMixL=Преобразователь частоты' нет "правых" аналогов как и у точек 'onSpecL=Анализатор спектра левый', 'onMixL=Преобразователь частоты(левый)'. Это потому, что они не нужны?
2. точка 'doPlayData=Два байта на PLAY' - почему 2 байта - потому, что 2 канала или потому, что 16 бит в сэмпле, или потому, что "так сделано" и содержимое не важно, а только факт?
3. 'onPlayData=Поток на PLAY' - как его использовать?
------------ Дoбавленo:
компиляторы жалуются на точки "FMin" и "FMax"
Add(InlineCode,14681589,133,180)
{
@Hint=#8:FFT_IFFT|
WorkPoints=#15:doSet=Установки|28:doRecData=Блок данных записи|28:doPlayData=Два байта на PLAY|24:doFFTL=FFT левого канала|25:doFFTR=FFT правого канала|34:doIFFTL=Обратные FFT левого канала|35:doIFFTR=Обратные FFT правого канала|32:doSpecL=Анализатор спектра левый|30:doMixL=Преобразователь частоты|
EventPoints=#24:onPlayData=Поток на PLAY|41:onEndRec=Конец приема блока данных записи|34:onFFTL=Окончание FFT левого канала|35:onFFTR=Окончание FFT правого канала|40:onIFFTL=Конец обратных FFT левого канала|41:onIFFTR=Конец обратных FFT правого канала|32:onSpecL=Анализатор спектра левый|37:onMixL=Преобразователь частоты(левый)|
DataPoints=#23:Freq=Частота дискретиз.|30:N1=длина FFT(кратна степени 2)|27:ArrayL=Массив спекта, левый|36:FMix=Опорная частота преобразователя|16:FMin=Нижний срез|17:FMax=Верхний срез|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|12: protected|20: StreamL:PStream;|9: public|23: _prop_Freq:integer;|21: _prop_N1:integer;|23: _prop_FMix:integer;|0:|25: _data_Data:THI_Event;|0:|17: N1:THI_Event;|19: Freq:THI_Event;|21: ArrayL:THI_Event;|19: FMix:THI_Event;|0:|25: onPlayData:THI_Event;|23: onEndRec:THI_Event;|21: onFFTL:THI_Event;|21: onFFTR:THI_Event;|22: onIFFTL:THI_Event;|22: onIFFTR:THI_Event;|22: onSpecL:THI_Event;|21: onMixL:THI_Event;|0:|53: procedure doRecData(var _Data:TData; Index:word);|54: procedure doPlayData(var _Data:TData; Index:word);|49: procedure doSet(var _Data:TData; Index:word);|50: procedure doFFTL(var _Data:TData; Index:word);|50: procedure doFFTR(var _Data:TData; Index:word);|51: procedure doIFFTL(var _Data:TData; Index:word);|51: procedure doIFFTR(var _Data:TData; Index:word);|51: procedure doSpecL(var _Data:TData; Index:word);|50: procedure doMixL(var _Data:TData; Index:word);|5: end;|0:|14:implementation|0:|3:var|53: al:Array [0..10000] of single;//Данные для обработки|31: ar:Array [0..10000] of single;|48: apl:Array [0..10000] of single;//Данные на PLAY|32: arl:Array [0..10000] of single;|48: wprp:Array [1..100] of single;//Таблица синусов|31: wpip:array [1..100] of single;|31: wpro:Array [1..100] of single;|31: wpio:Array [1..100] of single;|11: k:integer;|21: Left,Right:smallint;|19: leng,len:cardinal;|19: F,M,nn,FM:integer;|0:|39:procedure THiAsmClass.doSet;//Установки|10:label Me1;|36:var N2,Q,n,isign,mmax,istep:integer;|17: theta:single;|5:begin|49: nn := ReadInteger(_Data,N1,_prop_N1);//Длина FFT|64: F := ReadInteger(_Data,Freq,_prop_Freq);//Частота дискретизации|75: FM := ReadInteger(_Data,FMix,_prop_FMix);//Опорная частота преобразователя|42: M := 1; //Определение степени 2 длины FFT|10: N2 := nn;|21: Me1: N2 := N2 div 2;|15: if N2<>1 then|8: begin|15: M := M + 1;|13: goto Me1;|7: end;|37: Q := 1; //Таблицы синусов прямоеFFT|35: n := 2*nn; isign := 1; mmax := 2;|19: while n>mmax do|9: begin|24: istep := 2*mmax;|35: theta := 2*Pi/(isign*mmax);|44: wprp[Q] := -2.0*sqr(sin(0.5*theta));|30: wpip[Q] := sin(theta);|33: Q := Q+1; mmax := istep;|9: end;|40: Q := 1; //Таблицы синусов обратное FFT|36: n := 2*nn; isign := -1; mmax := 2;|19: while n>mmax do|9: begin|24: istep := 2*mmax;|35: theta := 2*Pi/(isign*mmax);|44: wpro[Q] := -2.0*sqr(sin(0.5*theta));|30: wpio[Q] := sin(theta);|33: Q := Q+1; mmax := istep;|9: end;|4:end;|0:|59:procedure THiAsmClass.doRecData;//Прием блока данных RECORD|18:var St,Sp:PStream;|16: i,j:integer;|32: ap:array [0..20000] of word;|5:begin|42: St := ReadStream(_data,_data_Data,nil); |25: if St = nil then Exit; |17: len := St.Size;|51: leng := len div 4;//Кол-во ячеек в каждом массиве|61: //move(al,apl,len*2);//Загрузка обработанных данных на PLAY|23: //move(ar,arl,len*2);|9: i := 0;|25: while i <= len div 2 do|8: begin|32: ap[i] := word(trunc(al[i]));|34: ap[i+1] := word(trunc(ar[i]));|13: inc(i,2);|7: end;|25: Sp := NewMemoryStream;|16: Sp.Size := 0;|20: Sp.Write(ap,len);|20: Sp.Position := 0;|30: _hi_onEvent(onPlayData,Sp);|51: for i := 1 to leng do //Сортировка по каналам L,R|9: begin |37: St.Read(Left,2);St.Read(Right,2);|15: j := 2*i-2;|65: al[j] := Left; al[j+1] := 0; //Загрузка новых данных с RECORD|33: ar[j] := Right; ar[j+1] := 0;|7: end;|36: k := 1; //Обнуление счетчика PLAY|25: _hi_onEvent(onEndRec);|0:|4:end;|0:|57:procedure THiAsmClass.doPlayData; //Выдача данных на PLAY|14:var j:integer;|11: a:word;|5:begin|28: //a := word(round(apl[5]));|34: j := ((k-1) div 2)*2;//2 * k - 2;|15: if odd(k) then|33: _hi_onEvent(onPlayData,apl[j])|38: else _hi_onEvent(onPlayData,arl[j]);|12: k := k + 1;|4:end;|0:|48:procedure THiAsmClass.doFFTL;//FFT левого канала|3:var|19: ii,Q : Integer;|17: jj : Integer;|16: n : Integer;|19: mmax : Integer;|16: m : Integer;|16: j : Integer;|20: istep : Integer;|16: i : Integer;|20: isign : Integer;|28: wtemp : Single;//Double;|25: wr : single;//Double;|26: wpr : single;//Double;|26: wpi : single;//Double;|25: wi : single;//Double;|28: theta : single;//Double;|28: tempr : single;//Double;|28: tempi : single;//Double;|5:begin|0:|15: isign := 1;|14: n := 2*nn;|11: j := 1;|10: ii:=1;|19: while ii<=nn do|9: begin|20: i := 2*ii-1;|19: if j>i then|13: begin|29: tempr := al[j-1];|27: tempi := al[j];|31: al[j-1] := al[i-1];|27: al[j] := al[i];|29: al[i-1] := tempr;|27: al[i] := tempi;|12: end;|21: m := n div 2;|33: while (m>=2) and (j>m) do|13: begin|21: j := j-m;|25: m := m div 2;|12: end;|17: j := j+m;|16: Inc(ii);|8: end;|22: mmax := 2; Q := 1;|19: while n>mmax do|9: begin|24: istep := 2*mmax;|37: //theta := 2*Pi/(isign*mmax);|42: //wpr := -2.0*sqr(sin(0.5*theta));|28: //wpi := sin(theta);|18: wr := 1.0;|18: wi := 0.0;|14: ii:=1;|31: while ii<=mmax div 2 do|13: begin|24: m := 2*ii-1;|18: jj:=0;|40: while jj<=(n-m) div istep do|17: begin|32: i := m+jj*istep;|28: j := i+mmax;|45: tempr := wr*al[j-1]-wi*al[j];|45: tempi := wr*al[j]+wi*al[j-1];|41: al[j-1] := al[i-1]-tempr;|37: al[j] := al[i]-tempi;|41: al[i-1] := al[i-1]+tempr;|37: al[i] := al[i]+tempi;|24: Inc(jj);|16: end;|24: wtemp := wr;|43: wr := wr*wprp[q]-wi*wpip[q]+wr;|46: wi := wi*wprp[q]+wtemp*wpip[q]+wi;|20: Inc(ii);|12: end;|34: mmax := istep; Q := Q + 1;|8: end;|24: {if InverseFFT then}|9: begin|13: I:=1;|24: while I<=2*nn do|13: begin|34: al[I-1] := al[I-1]/nn;|19: Inc(I);|12: end;|8: end;|23: _hi_onEvent(onFFTL);|4:end;|49:procedure THiAsmClass.doFFTR;//FFT правого канала|3:var|19: ii,Q : Integer;|17: jj : Integer;|16: n : Integer;|19: mmax : Integer;|16: m : Integer;|16: j : Integer;|20: istep : Integer;|16: i : Integer;|20: isign : Integer;|28: wtemp : single;//Double;|25: wr : single;//Double;|26: wpr : single;//Double;|26: wpi : single;//Double;|25: wi : single;//Double;|28: theta : single;//Double;|28: tempr : single;//Double;|28: tempi : single;//Double;|5:begin|0:|15: isign := 1;|14: n := 2*nn;|11: j := 1;|10: ii:=1;|19: while ii<=nn do|9: begin|20: i := 2*ii-1;|19: if j>i then|13: begin|29: tempr := ar[j-1];|27: tempi := ar[j];|31: ar[j-1] := ar[i-1];|27: ar[j] := ar[i];|29: ar[i-1] := tempr;|27: ar[i] := tempi;|12: end;|21: m := n div 2;|33: while (m>=2) and (j>m) do|13: begin|21: j := j-m;|25: m := m div 2;|12: end;|17: j := j+m;|16: Inc(ii);|8: end;|22: mmax := 2; Q := 1;|19: while n>mmax do|9: begin|24: istep := 2*mmax;|35: theta := 2*Pi/(isign*mmax);|42: //wpr := -2.0*sqr(sin(0.5*theta));|28: //wpi := sin(theta);|18: wr := 1.0;|18: wi := 0.0;|14: ii:=1;|31: while ii<=mmax div 2 do|13: begin|24: m := 2*ii-1;|18: jj:=0;|40: while jj<=(n-m) div istep do|17: begin|32: i := m+jj*istep;|28: j := i+mmax;|45: tempr := wr*ar[j-1]-wi*ar[j];|45: tempi := wr*ar[j]+wi*ar[j-1];|41: ar[j-1] := ar[i-1]-tempr;|37: ar[j] := ar[i]-tempi;|41: ar[i-1] := ar[i-1]+tempr;|37: ar[i] := ar[i]+tempi;|24: Inc(jj);|16: end;|24: wtemp := wr;|43: wr := wr*wprp[q]-wi*wpip[q]+wr;|46: wi := wi*wprp[q]+wtemp*wpip[q]+wi;|20: Inc(ii);|12: end;|34: mmax := istep; Q := Q + 1;|8: end;|24: {if InverseFFT then}|9: begin|13: I:=1;|24: while I<=2*nn do|13: begin|34: ar[I-1] := ar[I-1]/nn;|19: Inc(I);|12: end;|8: end;|23: _hi_onEvent(onFFTR);|4:end;|58:procedure THiAsmClass.doIFFTL;//обратные FFT левого канала|3:var|19: ii,Q : Integer;|17: jj : Integer;|16: n : Integer;|19: mmax : Integer;|16: m : Integer;|16: j : Integer;|20: istep : Integer;|16: i : Integer;|20: isign : Integer;|28: wtemp : single;//Double;|25: wr : single;//Double;|26: wpr : single;//Double;|26: wpi : single;//Double;|25: wi : single;//Double;|28: theta : single;//Double;|28: tempr : single;//Double;|28: tempi : single;//Double;|5:begin|16: isign := -1;|14: n := 2*nn;|11: j := 1;|10: ii:=1;|19: while ii<=nn do|9: begin|20: i := 2*ii-1;|19: if j>i then|13: begin|29: tempr := al[j-1];|27: tempi := al[j];|31: al[j-1] := al[i-1];|27: al[j] := al[i];|29: al[i-1] := tempr;|27: al[i] := tempi;|12: end;|21: m := n div 2;|33: while (m>=2) and (j>m) do|13: begin|21: j := j-m;|25: m := m div 2;|12: end;|17: j := j+m;|16: Inc(ii);|8: end;|22: mmax := 2; Q := 1;|19: while n>mmax do|9: begin|24: istep := 2*mmax;|37: //theta := 2*Pi/(isign*mmax);|42: //wpr := -2.0*sqr(sin(0.5*theta));|28: //wpi := sin(theta);|18: wr := 1.0;|18: wi := 0.0;|14: ii:=1;|31: while ii<=mmax div 2 do|13: begin|24: m := 2*ii-1;|18: jj:=0;|40: while jj<=(n-m) div istep do|17: begin|32: i := m+jj*istep;|28: j := i+mmax;|45: tempr := wr*al[j-1]-wi*al[j];|45: tempi := wr*al[j]+wi*al[j-1];|41: al[j-1] := al[i-1]-tempr;|37: al[j] := al[i]-tempi;|41: al[i-1] := al[i-1]+tempr;|37: al[i] := al[i]+tempi;|24: Inc(jj);|16: end;|24: wtemp := wr;|43: wr := wr*wpro[q]-wi*wpio[q]+wr;|46: wi := wi*wpro[q]+wtemp*wpio[q]+wi;|20: Inc(ii);|12: end;|34: mmax := istep; Q := Q + 1;|8: end;|16: //If inverse|10: { begin|13: I:=1;|24: while I<=2*nn do|13: begin|34: al[I-1] := al[I-1]/nn;|19: Inc(I);|12: end;|9: end;}|23: _hi_onEvent(onIFFTL);|4:end;|0:|59:procedure THiAsmClass.doIFFTR;//обратные FFT правого канала|3:var|19: ii,Q : Integer;|17: jj : Integer;|16: n : Integer;|19: mmax : Integer;|16: m : Integer;|16: j : Integer;|20: istep : Integer;|16: i : Integer;|20: isign : Integer;|28: wtemp : single;//Double;|25: wr : single;//Double;|26: wpr : single;//Double;|26: wpi : single;//Double;|25: wi : single;//Double;|28: theta : single;//Double;|28: tempr : single;//Double;|28: tempi : single;//Double;|5:begin|16: isign := -1;|14: n := 2*nn;|11: j := 1;|10: ii:=1;|19: while ii<=nn do|9: begin|20: i := 2*ii-1;|19: if j>i then|13: begin|29: tempr := ar[j-1];|27: tempi := ar[j];|31: ar[j-1] := ar[i-1];|27: ar[j] := ar[i];|29: ar[i-1] := tempr;|27: ar[i] := tempi;|12: end;|21: m := n div 2;|33: while (m>=2) and (j>m) do|13: begin|21: j := j-m;|25: m := m div 2;|12: end;|17: j := j+m;|16: Inc(ii);|8: end;|22: mmax := 2; Q := 1;|19: while n>mmax do|9: begin|24: istep := 2*mmax;|37: //theta := 2*Pi/(isign*mmax);|42: //wpr := -2.0*sqr(sin(0.5*theta));|28: //wpi := sin(theta);|18: wr := 1.0;|18: wi := 0.0;|14: ii:=1;|31: while ii<=mmax div 2 do|13: begin|24: m := 2*ii-1;|18: jj:=0;|40: while jj<=(n-m) div istep do|17: begin|32: i := m+jj*istep;|28: j := i+mmax;|45: tempr := wr*ar[j-1]-wi*ar[j];|45: tempi := wr*ar[j]+wi*ar[j-1];|41: ar[j-1] := ar[i-1]-tempr;|37: ar[j] := ar[i]-tempi;|41: ar[i-1] := ar[i-1]+tempr;|37: ar[i] := ar[i]+tempi;|24: Inc(jj);|16: end;|24: wtemp := wr;|43: wr := wr*wpro[q]-wi*wpio[q]+wr;|46: wi := wi*wpro[q]+wtemp*wpio[q]+wi;|20: Inc(ii);|12: end;|34: mmax := istep; Q := Q + 1;|8: end;|16: //If inverse|10: {begin|13: I:=1;|24: while I<=2*nn do|13: begin|34: ar[I-1] := ar[I-1]/nn;|19: Inc(I);|12: end;|9: end;}|23: _hi_onEvent(onIFFTR);|4:end;|56:procedure THiAsmClass.doSpecL;//Анализатор спектра левый|3:var|16: i,a:integer;|15: Arr:PArray;|14: Ind:TData;|14: Val:TData;|5:begin|27: Arr := ReadArray(ArrayL);|17: a := nn div 256;|9: i := nn;|21: while i <= 2*nn-8 do|7: begin|107: Val := _DoData(sqrt((sqr(al[i]) + sqr(al[i+1])+sqr(al[i+2])+sqr(al[i+3])+sqr(al[i+4])+sqr(al[i+5]))/3));|38: Ind := _DoData(i div a - nn div a);|21: Arr._Set(Ind,Val);|12: Inc(i,a);|6: end;|8: i := 7;|19: while i <= nn-1 do|7: begin|107: Val := _DoData(sqrt((sqr(al[i]) + sqr(al[i+1])+sqr(al[i+2])+sqr(al[i+3])+sqr(al[i+4])+sqr(al[i+5]))/3));|38: Ind := _DoData(i div a + nn div a);|21: Arr._Set(Ind,Val);|12: Inc(i,a);|6: end;|22: _hi_onEvent(onSpecL);|4:end;|0:|62:procedure THiAsmClass.doMixL;//Преобразователь частоты (левый)|14:var i:integer;|5:begin|21: _hi_onEvent(onMixL);|4:end;|0:|4:end.|
link(onEndRec,14681589:doFFTL,[(200,193)(200,169)(121,169)(121,207)])
link(onFFTL,14681589:doFFTR,[(205,200)(205,291)(98,291)(98,214)])
link(onFFTR,14681589:doMixL,[(194,207)(194,266)(121,266)(121,242)])
link(onIFFTL,14681589:doIFFTR,[(199,214)(199,276)(108,276)(108,228)])
link(onSpecL,14681589:doIFFTL,[(190,228)(190,260)(103,260)(103,221)])
link(onMixL,14681589:doSpecL,[(187,235)(187,253)(114,253)(114,235)])
link(FMin,3327504:Text,[(167,152)(146,152)])
link(FMax,6348894:Text,[(174,159)(195,159)])
}
Add(Edit,3327504,140,84)
{
Left=335
Top=30
Hint="Нижний срез"
Text="300"
PColor(onChange,8453888)
}
Add(Edit,6348894,189,84)
{
Left=385
Top=30
Hint="Верхний срез"
Text="4000"
PColor(onChange,8453888)
}