RadioRecorder(ラジオ番組自動録音装置)の製作 2013.8.23

    [Japanese][English]


    1.はじめに

     これまでに、ジャンクオーディオの修理で集めたミニコンポ2台を使って、ラジオ放送2番組を、月曜日から金曜日までの毎日と、その一週間分の再放送を土日に、コンポのタイマー機能を使ってMDに自動録音しています。

    ONKYOのミニコンポ2台で毎日録音

     わざわざコンポを2台も使っている理由はこうです。1枚のMDでは2番組を一週間分まとめて録音することができないこと。さらに、コンポのタイマー機能が貧弱で多彩な録音設定ができないことです。

     そんな訳で2台も使って録音を行っている訳ですが、80分のMDでは、一週間毎に新しいものと取り換えないと次の録音ができません。また、録音内容を、MDでずっと保存しておこうとすると何枚ものMDが必要になります。

     そこで、MDを増やさないようにMDからPCへの取込みを定期的に行ってMDを使い回すようにしていますが、MDからPCへの取込は、MDを再生してのアナログ取込となりますので時間がかかります。

     この煩わしさを何とかしたいと思って、今回製作したのが、RadioRecorder(ラジオ番組自動録音装置)です。


    2.機器構成

     製作したラジオ番組自動録音装置は、マイコンとラジオチューナーユニット、SDHC-32GBのSDカードで構成しています。装置の概要は、次のとおりです。

    製作したラジオ番組自動録音装置

     マイコンを使って、ラジオチューナーのチューニングを行い、チューナーから出力される受信音声信号をマイコンのA/D変換モジュールでマイコン内部のメモリにデジタルデータとして取り込みます。取り込んだ音声データは、SDカードにWAVファイルとして書き出します。

     音声取込は、44.1KHz、16ビット、ステレオで行ない、CD並みの品質を目指しましたが、マイコンのA/D変換モジュールが10ビット変換ですので、厳密には16ビット取込みとはなっていません。

     自動録音をするための録音スケジュールは、予めSDカードにテキストファイルとして格納しています。

     録音の開始、停止を制御するために、マイコンにカレンダー時計の機能をプログラムしました。

     正確な録音開始制御を行うために、毎正時、NHKラジオ放送の時報によって時刻補正を行うようにしました。これにより、常に誤差1秒以内の精度が保てるようになっています。


    2−1. チューナーユニット

     マイコンの制御で周波数設定ができ、音声信号が外部に取り出せるチューナー用のラジオICが、最近は手軽に入手できるようになりました。それらの中から適当なものを選択すれば良いのですが、今回は、ジャンクのミニコンポに内蔵されていたFM/AMチューナーユニットを流用しました。

     具体的には、ハードオフで、部品取り用として購入したKENWOODのミニコンポ「RXD-SJ3MD」から取り外したチューナーユニットを使いました。このコンポ、わずか200円の値札が付いていたので思わず買ってしまったものです。スピーカーや付属品はなく、本体のみです。

     チューナーユニットは、コンポのメイン基板と、15ピンのFFCケーブルで接続されていましたが、本装置の製作では、ユニットの端子に10芯のフラットリボンケーブルを直接半田付けしました。ケーブルのもう一方のマイコン基板との接続側には、ヘッダピン用のメスコネクタを取り付けました。

    ジャンクで手に入れた「RXD-SJ3MD」
    背面のチューナーユニットを外す
    これがチューナーユニット

    FFCケーブルで接続されていた
    チューナーICが使われている
    リボンケーブルをハンダ付けした

     チューナーユニットの端子の信号名は、コンポのメイン基板にシルク印刷されていましたので簡単に知ることができました。この中で、今回の製作に必要な信号のみを引き出しています。

     信号名から、マイコンからはシリアルで制御できる事がわかりましたが、具体的な信号プロトコルがわからないとマイコンのプログラムを書くことができません。そこで、チューナーユニットを分解して、部品を調べてみましたら、サンヨーの「LA1837」と「LC72131」が使われていました。ネットから、これらICのデータシートをダウンロードして、無事にプログラムを作ることができました。


    2−2. マイコン基板

     マイコンは、44.1KHzの高速サンプリングが余裕を持って出来るように、80MHzクロックの「PIC32MX695F512H」を使いました。ここ最近の工作で使い慣れたPICです。LQFP変換基板を使い、ユニバーサル基板の上に回路を製作しました。

     マイコン周りの回路図ならびに製作したマイコン基板を以下に示します。

    回路図
    マイコン基板(表)
    マイコン基板(裏)

     チューナーユニットから出力される音声信号レベルが少し低くかったので、オペアンプ(NJM2732)を使って軽く増幅するとともに、出力電圧のレベルシフトを行っています。オペアンプの出力は、PICのAN2,AN3のアナログ入力ピンに接続しています。

     もう一つのオペアンプ(LM358)では、コンパレータ回路を構成し、左チャンネルの音声信号を、パルス信号に変換しています。このパルス信号は、時報信号(ピッ、ピッ、ピッ、ポーン)を検出するためのもので、RD5で読み取るようにしています。

     チューナーの周波数設定のための制御信号(PLL-xxx)は、SPIモジュールなどは使用せずに、RG6-RG9のデジタルI/Oで行いました。

     SDカードは、SPI3モジュールを使って制御するようにしました。SDカードのカード検出や、書き込み禁止検出は、使用していません。これらの信号は、プログラム内で、常にカード挿入、書き込み可能に設定しています。

    USBでパソコンと接続
    リムーバルディスクと
    COMポートの複合デバイスとなる。
    録音開始時刻(月日時分)がファイル名となる。

     SDカードに格納している録音スケジュールファイルの内容更新や、録音済みWAVファイルの読み出し、カレンダー時計の初期値設定をパソコンから行えるように、USBでパソコンと接続できるようにしました。マイコン基板は、パソコンからは、CDC(コミュニケーションクラス)と、MSD(マスストレージ)の複合デバイスに見えます。

     SDカードは、リムーバルディスクとしてパソコンに認識されます。またハイパーターミナルなどのターミナルソフトを、USB接続したCOMポートを直接指定して起動すれば、ターミナル画面上から、マイコン内部の現在時刻の表示、変更やチューナーの周波数設定を行うことができます。

     その他、デバッグ出力用にUART2を、プログラム用にICSPを、動作モニター用に青、赤のLEDを設けています。チューナーが目的の周波数に設定されているかどうか確認できるように、音声モニター端子も設けました。ヘッドフォンアンプなどを接続すれば、受信放送の内容を確認できます。

     電源回路についてです。チューナーユニットの動作には、+9Vが必要です。PICやSDカードは、+3.3Vが必要です。+9V出力のACアダプターを使えば、電源ICが一個で済んだのですが、手元に+9Vのアダプタが無く、+12Vのアダプタと7809の3端子レギュレータがありましたので、回路図のような電源構成としました。


    3.ソフトウエア

     MPLAB IDEの上で、C32コンパイラを使ってC言語で開発しました。出来上がったプロジェクトファイル一式は、以下のとおりです。


     主な処理について、簡単に説明します。詳細については、ソースファイルを参照ください。


     SDカードの制御(ff.c mmc.c usb/msd.c)

     SDカードは、セクターを直接指定してのデータの読み書きが出来ますが、パソコン上からも簡単にアクセス出来るように、前作の「DriveRecorder」と同様に、Chan氏作成のFatファイルシステムを採用しました。

     PICのSPI3モジュールを使って制御しています。SDHCカードを使うと、20MHzクロックで読み書きします。

     「マイコン基板」の項でも説明しましたが、カードの挿入検出や書き込み禁止検出は使わずに、プログラム内で、常にカード挿入、書き込み可能の状態に設定しています。


     チューナーの制御(tuner.c)

     チューナーユニットに使われているIC 「LC72131」のデータシートに書かれているプロトコル仕様に則ってプログラムを作成しました。シリアル制御なので、SPIモジュールを使う方法もありますが、プロトコルフォーマットがやや複雑なので、今回は、デジタルピンのオンオフで制御しました。

     周波数を引数にして、Tuned()関数を呼び出せば、目的の周波数に設定できるようにしました。なお、引数の周波数の単位は、AMもFMも "KHz" に統一しました。85.1MHzに設定する場合には、Tuned(85100)として呼び出します。


     録音スケジュール(schedule.c)

     録音スケジュールは、全体で40スケジュールまで登録できるようにしました。ソースファイル冒頭のMAX_RESERVEの設定値を変更すれば、メモリの許す限り、更にスケジュールを増やす事が出来ます。

     一つのスケジュールは、構造体で、次のような構成にしています。

    
      struct schedule_t{
        unsigned long frequency;  // 受信周波数
        char year;  // -1, 1-99 
        char month; // -1, 1-12
        char day;   // -1, 1-31
        char wday;  // -1, 0-6(sun-sat)
        char bhh;   // 録音開始 時
        char bmm;   //     分
        char ehh;   // 録音停止 時
        char emm;   //     分
      };
    

     年、月、日、曜日の値に -1 が設定されると、その項目は常にマッチ状態となります。例えば、{ 85200, -1, -1, -1, -1, 6, 30, 7, 0 } のような設定の場合には、毎日6時30分から、7時まで、85.2MHzの放送を録音することになります。

     次のような設定 { 85200, -1, -1, -1, 0, 6, 30, 7, 0 } では、毎日曜日の6時半から7時までの録音となります。

     年月日が設定されていれば、その日限りの録音、1回だけの録音となります。


     録音スケジュールの設定は、SDカードのルートディレクトリに格納された "RECORD.TXT" というテキストファイルで行います。ファイルの記述書式、ならびに記述サンプルは、次のとおりです。

    
      #*** schedule plan order form
      # 
      # format1  order one day
      #   freq yyyy/mm/dd hh:mm hh:mm
      #
      # format2  every week day
      #   freq wday hh:mm hh:mm
      #   freq wday-wday hh:mm hh:mm
    
      86500 2013/12/01 05:00 06:00   2013年12月1日の5時から6時までの86.5MHzの放送、一回限りの録音
      89900 2013/12/24 23:30 00:30   2013年12月24日の深夜23:30分から翌25日の0時30分まで、89.9MHzの放送を録音
    
      85100 sat     07:00 07:50      85.1MHzの放送を、毎土曜日の7時から7時50分まで録音
      80200 sun     16:30 17:45
    
      83600 mon-fri 06:45 07:00      83.6MHzの放送を、毎月曜日から毎金曜日まで、6時45分から7時まで録音
      76500 mon-fri 08:30 08:40
      78500 sat-mon 01:20 01:35      78.5MHzの放送を、毎土曜日から毎月曜日まで、1時20分から1時35分まで録音
    

     録音時間が重なった場合には、先のスケジュールの録音はしますが、後の重なった方のスケジュールは、録音しません。

     毎分毎に、現在日時と各スケジュールで指定された録音開始日時を比較し、一致すれば、録音処理を開始します。

     "RECORD.TXT"ファイルのオープンや読み込みに、fopen()やfgets()関数を使っています。これらの関数を使ってSDカードにアクセスするために、open()やread()の低水準入出力関数を作成しました。


     録音処理(record.c)

     録音処理は次のように行っています。

     目的の周波数にチューナーを設定し、その後、A/D変換結果割り込みを有効にして、A/D変換モジュールを自動サンプリング、自動変換モードで起動します。これにより、変換完了毎に割り込みが発生します。

     この割り込み周期が、44.1KHzになるように、サンプリング時間、AD変換クロックを調整します。本製作では、1チャンネルあたり 11.05us に設定し、2チャンネル分の変換で、22.1us (45.294KHz)にしました。

     44.1KHzとの誤差が、2.7%ありますが、録音結果のWAVファイルをパソコンで再生してみると聴感上の違和感は全くありませんでした。また、左チャネルと右チャネルでサンプリングタイミングが、11.05usずれている訳ですが、これもまた聴感上は問題ありませんでした。

     割り込み処理の中で、メモリ上に設けた複数のバッファにA/D変換結果を順次書き込んで行きます。一つのバッファは、2チャンネル、16ビット、1024サンプル分を格納できる4096バイトの大きさを持っています。このバッファを16バッファ設けています。

     バッファに格納されたA/D変換結果は、一つのバッファが一杯になる毎に、順次SDカードのファイルへ書き出して行きます。

     SDカードへの書き出し処理中であっても、割り込み処理では、次の空きバッファに書き込みを行いますので、A/D変換結果の取りこぼしは起こらないはずです。

     ところが、時折、取りこぼしが発生します。FATの更新などのタイミングでSDカードへの書き出しに時間がかかる時があるようです。バッファは、16バッファありますので、その時間余裕は、(1024*15)/44100=0.348、約350msecもあるのですが、これでも足らないようです。

     PIC32MX695F512Hでは、RAMが128KBありますので、バッファの数を更に増やすことができますが、抜本的な対策として、Fat更新などの余分な処理を伴わない方法を採ることにしました。

     A/D変換結果を一旦、SDカードの一部のエリアに、セクターを直接指定して書き出し、録音終了後に、それらを読み出し、Fatファイルシステムのファイルとして書き戻す方法を考えました。

     これにより、データの取りこぼしは、発生しないようになりましたが、録音終了後に、この書き戻しのための時間が必要になり、時間が連続した録音が出来なくなりました。

     また、一時的に書き出すエリアは、Fatシステムの管理領域内にありますので運用上の注意が必要です。SDカードを領域分割するなどの対策が必要かと思っています。


     時報による時刻補正(jjydecord.c)

     プログラムしたカレンダー時計の時刻設定について、当初は、電波時計による自動設定を考えました。

     液晶表示が駄目になってお役御免となった電波時計が手元にありましたので、それを分解して電波受信モジュールを取り出して使うことにしました。

     電波時計は、昼間帯は、なかなかうまく受信できず、また窓際などの電波の受信状態の良い場所に設置が必要になるなど、使い勝手は決して良いわけではないのですが、日時が自動で設定出来るのは魅力です。

     そこで、受信データの解析プログラムまで書いてテストを始めたのですが、テスト中に電波受信モジュールを壊してしまったようで、全く受信できなくなりました。

    ジヤンクの電波時計の部品
    小さなドーター基板が受信モジュール
    受信モジュールを取り外す

     新たに電波時計を購入して分解するのも気がひけますし、電波受信回路を一から作るのも大変なので電波時計による方法は諦めて、どうせラジオを受信するのだからということで、時報による時刻補正を採用することにしました。

     電波時計の受信解析プログラムは、ソースファイルに残してありますが全くテストが出来ていません。

     時報による補正では、毎正時のタイミングを計ることはできますが、日時を知ることはできません。装置起動後に手動で日時設定を行うようにしました。USBでパソコンと接続し、パソコンから設定します。

     毎時59分45秒になると、NHKのラジオ放送を受信し、30秒間、時報信号の検出処理を行います。時報の検出は、パルス信号の数をカウントして行っています。

     時報が検出できた場合には、時刻補正を行い、検出できなかった場合には何もしません。これにより、プラスマイナス15秒以内の時刻ずれが補正できることになります。

     装置起動後の手動による日時の初期設定は、電波時計などを見ながらプラスマイナス15秒以内になるように行う必要があります。そうでないと補正ができません。

     なお、録音中には、この補正処理は動作しません。