VS1053 MP3 プレーヤー・シールドの調査 (2) 録音機能
今回はVS1053 MP3 プレーヤー・シールド の録音機能の調査です。
先日利用したライブラリを調べると、録音機能に関するAPIが存在しません。
Wikiにも解説がありません。
このボード、ピン構成やElecrowのWiki リンク先を見ると、
先日利用したライブラリを調べると、録音機能に関するAPIが存在しません。
Wikiにも解説がありません。
このボード、ピン構成やElecrowのWiki リンク先を見ると、
SparkFun のMP3 Player Shield がベースとなっているようです。
ベースのボードには録音機能(コンデンサーマイク、マイク端子)が無いんですよね。
それで、録音機能については何も解説が無いようです。
録音機能の実装
前置きが長くなりましたが、本題の録音機能について試してみました。
Ogg Vorbisという形式にてSDカード上にファイルとして録音します。
まずは、ボード上のコンデンサーマイクを使った録音のお試しです。
Adafruitのチュートリアルを参考にして、Adafruit_VS1053_Library をダウンロードし、
サンプルスケッチのrecode_ogg を動かしてみました。
1)利用するピンの変更(=>スケッチの変更)
2)SDライブラリの利用からSdFatライブラリの利用に変更(=>スケッチ、ライブラリの変更)
3)VS1053 ogg encoder プラグインの変更(=>スケッチの変更)
Adafruit_VS1053_Library のサンプルスケッチ recode_ogg のフォルダに
モノラル 44.1KHz, 高品質録音のプラグイン v44k1q05.img が用意されているのですが、
Arduinoの処理が間に合わず、音飛び発生や、ファイルが壊れて再生出来ずでした。
そこで、別のプラグインを利用しました。
公式サイト(VLSI社) には、別のプラグインが公開されてます。
用途に応じて選択して利用することが出来ます。下記のリンクからダウンロードできます。
・VS1053 Ogg Vorbis Encoder Application
http://www.vlsi.fi/fileadmin/software/VS10XX/vs1053-vorbis-encoder-170c.zip
解凍したフォルダprofilesの中の vencXXkYqZZ.img がプラグインです。
下記の組み合わせで複数用意されています。
XX: サンプリング周波数 08: 8kHz、16:16kHz、44:44kHz、
ライブラリの修正
Sdfat対応のために、ヘッダーファイル Adafruit_VS1053.hに PREFER_SDFAT_LIBRARY の定義を追加します。
#define ADAFRUIT_VS1053_Hの次の行に追加しました。
ベースのボードには録音機能(コンデンサーマイク、マイク端子)が無いんですよね。
それで、録音機能については何も解説が無いようです。
商品 SparkFun MP3 Player Shield (チュートリアル MP3 Player Shield Hookup Guide V15)

(チュートリアルのMP3 Player Shield Hookup Guide V15 はこれはこれで参考になります)
う~ん、困った..
色々と調べると、
VS1053の公式フォーラム(VSDSP Forum)を見るとAdafruitのボード用の
ライブラリ(Adafruit_VS1053_Library)を使うと録画が出来ると判明しました。
参考: AdafruitのVS1053ボード
VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4

チュートリアル Adafruit VS1053 MP3/AAC/Ogg/MIDI/WAV Codec Breakout Tutorial
録音機能の実装
前置きが長くなりましたが、本題の録音機能について試してみました。
Ogg Vorbisという形式にてSDカード上にファイルとして録音します。
まずは、ボード上のコンデンサーマイクを使った録音のお試しです。
Adafruitのチュートリアルを参考にして、Adafruit_VS1053_Library をダウンロードし、
サンプルスケッチのrecode_ogg を動かしてみました。
1)利用するピンの変更(=>スケッチの変更)
2)SDライブラリの利用からSdFatライブラリの利用に変更(=>スケッチ、ライブラリの変更)
3)VS1053 ogg encoder プラグインの変更(=>スケッチの変更)
VS1053用プラグインのダウンロード
Adafruit_VS1053_Library のサンプルスケッチ recode_ogg のフォルダに
モノラル 44.1KHz, 高品質録音のプラグイン v44k1q05.img が用意されているのですが、
Arduinoの処理が間に合わず、音飛び発生や、ファイルが壊れて再生出来ずでした。
そこで、別のプラグインを利用しました。
公式サイト(VLSI社) には、別のプラグインが公開されてます。
用途に応じて選択して利用することが出来ます。下記のリンクからダウンロードできます。
・VS1053 Ogg Vorbis Encoder Application
http://www.vlsi.fi/fileadmin/software/VS10XX/vs1053-vorbis-encoder-170c.zip
解凍したフォルダprofilesの中の vencXXkYqZZ.img がプラグインです。
下記の組み合わせで複数用意されています。
XX: サンプリング周波数 08: 8kHz、16:16kHz、44:44kHz、
Y: 1:モノラル、2:ステレオ
ZZ: 品質00~05 or 10 数字が大きいほど高品質
試した感じでは、44kHzでは、ステレオ録音は処理が追いつきません。
44kHzでは モノラル venc44k1q04.img 、
16kHzでは モノラル venc16k1q10.img 、ステレオ venc16k2q5.img
がちょうど良い感じでした。
ここでは、venc44k1q04.img を v44k1q04.img にファイル名を変更して
SDカードのルートフォルダにコピーします。
ZZ: 品質00~05 or 10 数字が大きいほど高品質
試した感じでは、44kHzでは、ステレオ録音は処理が追いつきません。
44kHzでは モノラル venc44k1q04.img 、
16kHzでは モノラル venc16k1q10.img 、ステレオ venc16k2q5.img
がちょうど良い感じでした。
ここでは、venc44k1q04.img を v44k1q04.img にファイル名を変更して
SDカードのルートフォルダにコピーします。
ライブラリの修正
Sdfat対応のために、ヘッダーファイル Adafruit_VS1053.hに PREFER_SDFAT_LIBRARY の定義を追加します。
#define ADAFRUIT_VS1053_Hの次の行に追加しました。
#ifndef ADAFRUIT_VS1053_H
#define ADAFRUIT_VS1053_H
#define PREFER_SDFAT_LIBRARY
スケッチの修正
ピン割り付けを変更しています。録音開始のボタンはD3を使いました。
/*************************************************** This is an example for the Adafruit VS1053 Codec Breakout Designed specifically to work with the Adafruit VS1053 Codec Breakout ----> https://www.adafruit.com/products/1381 Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ // This is a very beta demo of Ogg Vorbis recording. It works... // Connect a button to digital 7 on the Arduino and use that to // start and stop recording. // A mic or line-in connection is required. See page 13 of the // datasheet for wiring // Don't forget to copy the v44k1q05.img patch to your micro SD // card before running this example! // include SPI, MP3 and SD libraries #include <SPI.h> #include <Adafruit_VS1053.h> // SDライブラリからSdFatライブラリの利用に変更 by たま吉さん //#include <SD.h> #include "SdFat.h" SdFat SD; // ピン割り付けの変更 by たま吉さん // define the pins used //#define RESET 9 // VS1053 reset pin (output) //#define CS 10 // VS1053 chip select pin (output) //#define DCS 8 // VS1053 Data/command select pin (output) //#define CARDCS A0 // Card chip select pin //#define DREQ A1 // VS1053 Data request, ideally an Interrupt pin #define RESET 8 // VS1053 reset pin (output) #define CS 6 // VS1053 chip select pin (output) #define DCS 7 // VS1053 Data/command select pin (output) #define CARDCS 9 // Card chip select pin #define DREQ 2 // VS1053 Data request, ideally an Interrupt pin //#define REC_BUTTON 7 #define REC_BUTTON 3 Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer(RESET, CS, DCS, DREQ, CARDCS); File recording; // the file we will save our recording to #define RECBUFFSIZE 128 // 64 or 128 bytes. uint8_t recording_buffer[RECBUFFSIZE]; void setup() { Serial.begin(115200); Serial.println("Adafruit VS1053 Ogg Recording Test"); // initialise the music player if (!musicPlayer.begin()) { Serial.println("VS1053 not found"); while (1); // don't do anything more } musicPlayer.sineTest(0x44, 500); // Make a tone to indicate VS1053 is working if (!SD.begin(CARDCS)) { Serial.println("SD failed, or not present"); while (1); // don't do anything more } Serial.println("SD OK!"); // Set volume for left, right channels. lower numbers == louder volume! musicPlayer.setVolume(10,10); // when the button is pressed, record! pinMode(REC_BUTTON, INPUT); digitalWrite(REC_BUTTON, HIGH); // load plugin from SD card! We'll use mono 44.1KHz, high quality // プラグインの変更 by たま吉さん (mono 44.1KHz, middle quality) // if (! musicPlayer.prepareRecordOgg("v44k1q05.img")) { if (! musicPlayer.prepareRecordOgg("v44k1q04.img")) { Serial.println("Couldn't load plugin!"); while (1); } } uint8_t isRecording = false; void loop() { if (!isRecording && !digitalRead(REC_BUTTON)) { Serial.println("Begin recording"); isRecording = true; // Check if the file exists already char filename[15]; strcpy(filename, "RECORD00.OGG"); for (uint8_t i = 0; i < 100; i++) { filename[6] = '0' + i/10; filename[7] = '0' + i%10; // create if does not exist, do not open existing, write, sync after write if (! SD.exists(filename)) { break; } } Serial.print("Recording to "); Serial.println(filename); recording = SD.open(filename, FILE_WRITE); if (! recording) { Serial.println("Couldn't open file to record!"); while (1); } musicPlayer.startRecordOgg(true); // use microphone (for linein, pass in 'false') } if (isRecording) saveRecordedData(isRecording); if (isRecording && !digitalRead(REC_BUTTON)) { Serial.println("End recording"); musicPlayer.stopRecordOgg(); isRecording = false; // flush all the data! saveRecordedData(isRecording); // close it up recording.close(); delay(1000); } } uint16_t saveRecordedData(boolean isrecord) { uint16_t written = 0; // read how many words are waiting for us uint16_t wordswaiting = musicPlayer.recordedWordsWaiting(); // try to process 256 words (512 bytes) at a time, for best speed while (wordswaiting > 256) { //Serial.print("Waiting: "); Serial.println(wordswaiting); // for example 128 bytes x 4 loops = 512 bytes for (int x=0; x < 512/RECBUFFSIZE; x++) { // fill the buffer! for (uint16_t addr=0; addr < RECBUFFSIZE; addr+=2) { uint16_t t = musicPlayer.recordedReadWord(); //Serial.println(t, HEX); recording_buffer[addr] = t >> 8; recording_buffer[addr+1] = t; } if (! recording.write(recording_buffer, RECBUFFSIZE)) { Serial.print("Couldn't write "); Serial.println(RECBUFFSIZE); while (1); } } // flush 512 bytes at a time recording.flush(); written += 256; wordswaiting -= 256; } wordswaiting = musicPlayer.recordedWordsWaiting(); if (!isrecord) { Serial.print(wordswaiting); Serial.println(" remaining"); // wrapping up the recording! uint16_t addr = 0; for (int x=0; x < wordswaiting-1; x++) { // fill the buffer! uint16_t t = musicPlayer.recordedReadWord(); recording_buffer[addr] = t >> 8; recording_buffer[addr+1] = t; if (addr > RECBUFFSIZE) { if (! recording.write(recording_buffer, RECBUFFSIZE)) { Serial.println("Couldn't write!"); while (1); } recording.flush(); addr = 0; } } if (addr != 0) { if (!recording.write(recording_buffer, addr)) { Serial.println("Couldn't write!"); while (1); } written += addr; } musicPlayer.sciRead(VS1053_SCI_AICTRL3); if (! (musicPlayer.sciRead(VS1053_SCI_AICTRL3) & _BV(2))) { recording.write(musicPlayer.recordedReadWord() & 0xFF); written++; } recording.flush(); } return written; }
ボタンを押すと録音開始、再度押して録音終了です。
(ボタン操作がちょっとシビアで、瞬間的に押さないと開始・終了を繰り返します)
動作状況は、シリアルコンソールで確認できます。
oggファイルの再生は、ブラウザのChromeにドラッグ&ドロップして再生しました。
ただし、現時点では
・音が小さい
(ボタン操作がちょっとシビアで、瞬間的に押さないと開始・終了を繰り返します)
動作状況は、シリアルコンソールで確認できます。

oggファイルの再生は、ブラウザのChromeにドラッグ&ドロップして再生しました。
ただし、現時点では
・音が小さい
・音質が今一
でした。
もうちょっとどうにかならないか、調べてみます。
でした。
もうちょっとどうにかならないか、調べてみます。
« VS1053 MP3 プレーヤー・シールドでMIDIファイルの再生 | トップページ | おもちゃ「ちっちゃなミーニャ」の修理 »
「arduino」カテゴリの記事
- Freenove Mecanum ホイール カー キットを購入しました(2025.05.28)
- Arduino IDE+Arduino STM32環境で指定と異なるgccが使われてしまう(2025.01.23)
- Zorin OSでArduino Uno互換機(CH340)が認識しない(2025.01.19)
- Arduino IDE 2.3.4でArduino STM32を利用する(2025.01.12)
- Arduino用 SKK日本語変換ライブラリの開発 その1(2024.12.28)
« VS1053 MP3 プレーヤー・シールドでMIDIファイルの再生 | トップページ | おもちゃ「ちっちゃなミーニャ」の修理 »

コメント