2024年10月26日土曜日

FV-1 長時間delayについて

 非常に久しぶりになります。

最近遊んでる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の遅れとなります。

入力値D0D1D2D3出力
入力=11XXX->X
入力=出力X1XX
入力=出力XX1X
入力=出力1XX1
入力=221XX->X
入力=出力X21X
入力=出力1X21
入力=出力21X2
入力=3321X->X
入力=出力1321
入力=出力2132
入力=出力3213
入力=44321-> 1
入力=出力2432
入力=出力3243
入力=出力4324
入力=55432->2
入力=出力3543
入力=出力4354
入力=出力5435
入力=66543->3
入力=出力4654
入力=出力5465
入力=出力6546
入力=77654->4

ソフトを工夫して、最後にSCALEの設定だけで1秒から8秒まで変化させることができるようになりました。そこがこのプログラムの面白いところです。

ちなみに間違ってSCALEに5とか入れても正常に動作するようです。Delayの長さが特別なときにはSCALEはいくつでもうまく行くのかもしれません??!!

一応source fileをこちらに置きます。

 今回の実験はこれにて終了。