四月は案の定忙しく、結局5月に割り込んでしまいました。前回、プリアンプの動作をブレッドボードで確認できましたので、今回は基板に収めることにしました。思ったよりも小さなユニバーサル基板に収めることができました。





前回との変更点が一点あります。前回、電源をデジタル電源3.3Vを利用しましたが、使用したオペアンプは1Vから動作可能ということに気づいたので、マイクバイアス電源(2V)を使うことにしました。これでマイク端子だけでエレキギターの音を取り込めます。





実装してSPRESENSEに装着をしてみました。プリアンプらしくボリュームはマイク入力へのレベル調整のためにつけています。これによってデジタル処理ではないですがオーバードライブが可能になります。






■ プリアンプの動作を確認する
何もせずにバイアス電源をあたってみると、なんと0V。あれ?ここって2V出てるんじゃなかったっけ?と思って慌てたのですが、サンプルのレコーダーアプリをインストールしてみたら、2Vが出力されていました。さすが省電力を意識した設計になっています。

プリアンプにギタープラグを入れて、マイク入力の波形をオシロスコープであたってみました。無事にアンプ出力が出ていることが確認できました。





■ SPRESENSEでエレキギターの音を出す
ハードウェアの準備は全てできましたので、いよいよソフトウェアの出番です。ギターの音をそのままスルーで出力するようにプログラミングします。なるべく遅延が小さくなるようにフレームはできるだけ小さくしてみました。



#include <MediaRecorder.h>
#include <MediaPlayer.h>
#include <OutputMixer.h>
#include <MemoryUtil.h>

MediaRecorder *theRecorder;
MediaPlayer *thePlayer;
OutputMixer *theMixer;

const int32_t s_buffer_size = 4096*sizeof(int16_t);
uint8_t s_buffer[s_buffer_size];
uint8_t out_buffer[s_buffer_size];
int request_size = 128 * sizeof(int16_t);
int read_size;

/* callback functions */
static void attention_callback(const ErrorAttentionParam *atprm) {}

static bool mediarecorder_event_callback(AsRecorderEvent event, uint32_t result, uint32_t sub_result) {
return true;
}

static void outputmixer_event_callback(MsgQueId requester_dtq, MsgType reply_of, AsOutputMixDoneParam *done_param) { }

static void outmixer_rendering_callback(int32_t identifier, bool is_end) {
AsRequestNextParam next;
next.type = (!is_end) ? AsNextNormalRequest : AsNextStopResRequest;
AS_RequestNextPlayerProcess(AS_PLAYER_ID_0, &next);
return;
}

static bool mediaplayer_event_callback(AsPlayerEvent event, uint32_t result, uint32_t sub_result) {
return true;
}

void mediaplayer_decode_callback(AsPcmDataParam pcm_param) {
theMixer->sendData(OutputMixer0, outmixer_rendering_callback, pcm_param);
}

/* setup function from here */
void setup() {
initMemoryPools();
createStaticPools(MEM_LAYOUT_RECORDINGPLAYER);

Serial.println("Init Audio Library");
theRecorder = MediaRecorder::getInstance();
thePlayer = MediaPlayer::getInstance();
theMixer = OutputMixer::getInstance();

theRecorder->begin();
thePlayer->begin();

Serial.println("initialization MediaRecorder, MediaPlayer and OutputMixer");
theMixer->activateBaseband();

thePlayer->create(MediaPlayer::Player0, attention_callback);
theMixer->create(attention_callback);

theRecorder->activate(AS_SETRECDR_STS_INPUTDEVICE_MIC, mediarecorder_event_callback);
thePlayer->activate(MediaPlayer::Player0, AS_SETPLAYER_OUTPUTDEVICE_SPHP, mediaplayer_event_callback);
theMixer->activate(OutputMixer0, outputmixer_event_callback);

usleep(100000);

Serial.println("Initialize Recorder");
theRecorder->init(AS_CODECTYPE_LPCM, AS_CHANNEL_MONO, AS_SAMPLINGRATE_16000, AS_BITLENGTH_16, 0);

Serial.println("Initialize Player");
thePlayer->init(MediaPlayer::Player0, AS_CODECTYPE_WAV, "/mnt/sd0/BIN", AS_SAMPLINGRATE_16000, AS_CHANNEL_MONO);

theMixer->setVolume(-100, -100, -100);

Serial.println("Start Recorder");
theRecorder->start();

/* fill the sound data to FIFO before starting the player */
int frame_size = 0;
while (frame_size < request_size) {
err_t err = theRecorder->readFrames(s_buffer, request_size, &read_size);
if (err != 0) {
Serial.println("Error! readFrames: read_size = " + String(read_size));
}

if (read_size > 0) {
memset(out_buffer, 0, s_buffer_size);
memcpy(out_buffer, s_buffer, read_size);
thePlayer->writeFrames(MediaPlayer::Player0, out_buffer, read_size);
frame_size += read_size;
}
}

Serial.println("Start Player");
thePlayer->start(MediaPlayer::Player0, mediaplayer_decode_callback);
}

/* loop function from here */
void loop() {

int ret = theRecorder->readFrames(s_buffer, request_size, &read_size);
if (ret != 0) {
Serial.println("Error! readFrames: read_size = " + String(read_size));
}

if (read_size > 0) {
memset(out_buffer, 0, s_buffer_size);
memcpy(out_buffer, s_buffer, read_size);
thePlayer->writeFrames(MediaPlayer::Player0, out_buffer, read_size);
}
}



さて、実際のサウンドを聞いてみましょう。マイク入力のレンジ 0.9Vpp に対して 1.0Vpp 程度で入力してオーバードライブをかけてみました。それらしく聞こえるものですね。





聞いていただいてわかるように遅延量が大きいです。いろいろエフェクトを考える前に、この遅延をなんとかしたいところですが、これ以上短くできる気がしない…
(´・ω・`)





JRC(新日本無線) 1回路 低雑音 オペアンプ NJM5534DD (5個セット)

  • 出版社/メーカー: JRC(新日本無線)
  • メディア:



SONY SPRESENSE メインボード CXD5602PWBMAIN1

  • 出版社/メーカー: スプレッセンス(Spresense)
  • メディア: Tools & Hardware



SONY SPRESENSE 拡張ボード CXD5602PWBEXT1

  • 出版社/メーカー: スプレッセンス(Spresense)
  • メディア: Tools & Hardware