非常に久しぶりになります。
最近遊んでるDSPがありまして、その使い方を考えていたら面白い実験ができたので報告します。
使っているチップはSpin Semiconductorという会社のFV-1です。
FV-1は28ピンのICにステレオの24bitAD, 24bitDAが内蔵され32kHzサンプリングでき、32kワードのディレイ専用メモリがあって、1秒までのディレイは簡単に作れます。また、開発環境もメーカーから提供されていて、Arduinoのように簡単に使えます。
今回おこなった実験は1秒しか無いDelay用メモリをより長く使うために、数サンプル毎に1度だけ書き込むようにして、音質は顧みず長さだけ長くしてみました。
DSP内では整数のカウンターを使う方法がよく分からず、固定小数点表記カウンタを使ってます。オシロで見てみると、これでカウントされているようです。
これで、ディレイがどうなるか見てみます。
確かに4秒程度信号が遅れているのがわかります。
しかし、ディレイでの波形は8kHzサンプル相当なので、1周期16サンプルなのでガタガタの波形になって以下の様な感じ。
でも、一応動作しているようです。これを実際に使うためには、delayの前にローパスフィルタを、ディレイの後にもローパスフィルタを入れると綺麗な波形になりそうです。
テストプログラムはこんな感じです。
; Hideaki Nii 2024/10/26
; FV-1 spinasm
; LongDelayTest.spn
; More than 1 second test
;
; INPUT L: delay in
; OUTPUT L: delay out
; OUTPUT R: the sampling timing signal for debug
SCALE equ 4 ; The length of delay (seconds), 1 or 2 or 4 or 8
INITCNT equ 0.75
INITVAL equ 0.8
DECCNT equ - INITVAL / SCALE
Buf MEM 32767
CNT equ REG2
DELAYIN equ REG3
DELAYOUT equ REG4
;------ Read AD
SOF 0,0
RDAX ADCL,1
WRAX DELAYIN,0
;------ Startup
SKP run, CNTLOOP
SOF 0,INITCNT
WRAX CNT,0
; ------ Loop Main
CNTLOOP:
RDAX CNT,1
SOF 1.0, DECCNT
SKP gez, UPDATE
; ------ overflow
SOF 0, INITCNT
WRAX CNT,0
;------ ADIN
RDAX DELAYIN,1.0
WRA Buf,0
RDA buf#,1.0
WRAX DELAYOUT,0
SKP run, UPDATE_E
UPDATE:
WRAX CNT,0
;------ FEEDBACK
rda buf#,1.0
wra Buf,0
UPDATE_E:
;------ Output
RDAX DELAYOUT,1
WRAX DACL,0
RDAX CNT,1
WRAX DACR,0
;------ END
このDSPではDELAYメモリは自動的にシフトして行くのと同じように動くので、delayメモリのアドレス0に値を書き込んで、アドレス1を読むとそれだけで1サイクル遅らせることができるのです。そのために専用のコマンドがあって、rdaとwraというコマンドで簡単に読み書きできます。
このソフトでは、カウンタがSCALEの値である4を数えてオーバーフローする時だけADの値をdelayに書き込み、それ以外のタイミングではdelayの一番最後を最初に戻す仕組みになってます。
例えば、delayが長さ3としてSCALE=4となるような例の遷移の様子を以下に示します。入力には4回に一度新しい値が書き込まれ、出力には特定の場合だけ出力されます。この例ではDelay長*SCALE = 3*4 = 12の遅れとなります。
ソフトを工夫して、最後にSCALEの設定だけで1秒から8秒まで変化させることができるようになりました。そこがこのプログラムの面白いところです。
ちなみに間違ってSCALEに5とか入れても正常に動作するようです。Delayの長さが特別なときにはSCALEはいくつでもうまく行くのかもしれません??!!
一応source fileをこちらに置きます。
今回の実験はこれにて終了。
0 件のコメント:
コメントを投稿