2009-05-20 23 views
6

スピーカーでリアルトーンを再生するようにマイクロコントローラー(ATMega128)をプログラムする場合、どうすればいいですか?スピーカーに音を送る方法

は、私は別の振幅値を送信するためにデジタル/アナログ変換器を使用する必要がありますか、またはそれは、周波数の変化で十分ですか?いずれにしても、スピーカーが受信する必要がある周波数と振幅の値をどのようにエンコードしますか?何らかの周波数多重化が必要ですか?私は話し手と簡単な音を作ることについて話しているわけではありません。私はあなたがopen source MP3 playerを見て、彼らはそれを行う方法を見ることができました

答えて

0

すべての楽器、ボーカルなどで、実際の曲を再生したいです。私の推測では、まともな品質の音を出すにはD/Aコンバーターが必要です。ヘッダ
2)すべての1 /第二万二千百秒取り除く)

1:

+0

興味深いプロジェクトですが、不運にも、サウンドデコード部分をサードパーティのチップに「吸収」しました。 "オンチップのもう1つのチップは、VLSI、フィンランドのVS1011です。これは.mp3および.wavデコーダチップです。 DAC、ヘッドフォンアンプを1つの28ピンパッケージにまとめました。 私はそれをやった後、学習のためだけです。 – palako

6

あなたは非圧縮8ビット22.1   kHzのモノラル波ファイルを持っていると仮定
2.1)8ビットを読むを
2.2 )スピーカー

これはあなたを与えるだろう[22.1   kHzの/ 8ビット/モノラル]音質にそれを送る)話し手の電圧範囲
2.3に変換するDACを使用し、現実的なサンプルを再生するための簡単な方法です。

さまざまなシンセサイザーに必要なすべての周波数が必要です。たとえば、PCスピーカーは事実上1ビットです。 ( 'none'と 'maximum'よりも)異なる振幅を持つためには、パルス幅変調などのトリックが必要かもしれません(スピーカーのダイアフラムが効果的に2つ以上のポジションを持つように周りの周波数をシフトします)。

しかし、それを気にする必要はありません。あなたがする必要があることはスピーカーで毎秒22,100または44,200音サンプルを吐き出すことです。振幅を示すために1サンプルあたり8ビットまたは16ビットと言います。

+0

非常に面白いです。あなたの答えから、私はWAVファイルが実際には音そのものを非常に現実的に表現していると思います。 WAVをそれが表すアナログ信号に変換するだけです。私はこれを試してみましょう。 – palako

+2

DAC部分は、(比較的)単純なR-2Rラダーで実現できます。 http://en.wikipedia.org/wiki/Resistor_Ladder。 – Evansbee

+1

これはWAVファイルによって異なります。 WAV形式は実際には圧縮されたオーディオを含むことができます - 完全な形式仕様はここで入手できます:http://msdn.microsoft.com/en-us/library/ms713497.aspx –

1

あなたがresistor ladderを使用して、独自のデジタル・アナログ変換器を構築することができ、特に創造的な感じている場合。

0

ATMega128に空き容量がなく、あまりにも奇妙なことをすることはありません。スピーカ(小2" 以下)を接続する最も簡単な方法は、抵抗を介してである。出力の電流シンク能力をチェックし、それに応じてRを計算する。生成トーンに関して、出力の基本スイッチとして

---------------------- +V 
    | 
    \ 
    /R 
    \ 
    /   ---------- 
    |    | 
    | ------  | 
    ----| |-----| Microcontroller 
     / \  | 
     -------- | 
     Speaker --------- 

あなたはアナログサウンドの近似を生成するためにパルス幅変調を使うことができます(ここに入るにはあまりにも複雑で、おそらくAtMegaには十分なパフやストレージがありません)。これはオーディオドライバを作るための方法でした古き良き時代に無いサウンドカード(スピーカーのみで構築された)を搭載したPCのため...

2

今日では、8ビット・マイクロコントローラからMP3ファイルを再生するのは簡単で安価でもあります。あなたは、メモリのデを必要としますバイス(例えばSDカード)とMP3チップセットとの間の通信を可能にする。たとえばarticleを参照してください。 avrfreaksにもっと多くの情報があります。そこには、外部のチップなしでサウンドを再生するための記事もあります。

あなたはPulse-width modulation(PWM)との基本的なサウンドを再生することができますが、実際の曲のためにあなたは、DACが必要になります。私はDACとソフトウェアだけを使ってMP3ファイルを再生するプロジェクトを見てきましたが、より強力なARMマイクロコントローラが関わっていました。

0

Arduinoを使用している場合は、Lady AdaのWaveShieldを22ドルで購入できます。 Lady Adaは、購入可能な多くのArduino goodiesを提供しています。いくつかの例は、GPS、イーサネット、ステッパー/サーボシールドです。

+0

このプロジェクトではarduinoを使用していません。私は実際にそれを実装することに興味があり、最終結果ではありません。しかし、私はそのサイトを私のarduinoプロジェクトにブックマークしておきました。ありがとう! – palako

4

私は似たようなことを試しました。まず、実際の曲を保存するのに十分なメモリがマイクロコントローラにはありません。それを処理するには外部メモリが必要です。これは、外部フラッシュやEEPROMなどにSPIインターフェイスを使用することを意味します。 SDも良いです - 私はSPIスタイルのインターフェイスだと思います。 ATMカードがSDカードとインターフェースするためのコードがあります。

第2の大きな問題は、適切な形式でデータを取得することです。私がこれを行う方法は、さまざまな電圧レベルを作成するためにpulse-width modulation(PWM)を使用することです。私はあなたがあなたのサウンドに16ビットの忠実度を持つことができるように、あなたはそのマイクロコントローラ上に16ビットのPWMを持っていると信じています。スペースに問題がある場合は、代わりに8ビットPWMを使用できます。したがって、あなたのサウンドデータは8または16ビットのPCMでなければならず、0x0000が最低値、0xFFFFが最高値です。高忠実度の音楽が必要な場合は、良い倍音などを得るには44   KHzのサンプリングレートが必要です。私はこれがPCMだと信じています - それはPC上で呼ばれているのと同じです。

これらの値はすべて5分になりますが、5 * 60 * 44000 = 13,200,000の16ビット値は211,200,000ビット(211メガビット、26.4メガバイト)です。それらは生データのストレージ要件です。 MP3は可能性があります - そのための外部チップがありますが、まだ大きなスペースが必要です。

毎秒1/44000秒ごとにPWMレジスタの値を更新します。あなたのPWM周波数は、4または5だけ高くなければなりません。つまり、値ごとに5 PWMサイクルです。

それはあなたの一般的なアルゴリズムです - PWMレジスタの値を更新し、それが最後まで行かせてください。出力制限周波数のフィルタは、少なくとも20KHzの可聴帯域(オーディオファンならばさらに)に必要です。 RCフィルタが動作しますが、私はアクティブなフィルタを使用します。PWMを使用している場合、出力電圧範囲は通常0〜5V、平均電圧は約2.5Vです。スピーカーはDCレベルが好きではありません。 0の平均電圧を持つかなり正弦波。アクティブなフィルタは電圧レベルを調整し、負の電圧を供給するために二重電源を使用する必要があります。大きなポンピングベースの信号を増幅することもできます。スピーカーを吹かないでください。

MP3はおそらくPCMの方が良いでしょう。そこにチップがあります:http://www.sparkfun.com/commerce/product_info.php?products_id=8892

これは、マイクロコントローラ全体です。そしてあなたはすでにそれを持っています。しかし、それに直面しましょう - ATMegaはあなたがジャズアップしても、すぐにMP3をやるつもりはありません。

上記のwavehieldのように見えますが、これは基本的にこれを行います - PCMの格納にはSDカードを使用し、サウンド用の外部アンプは使用します。がんばろう!

+0

Sparkfunのリンクが壊れているようです。 –

2

安定したトーンを生成する1つの方法は、ダイレクトデジタル合成です。専用チップまたは抵抗ラダーのいずれかのDACが必要です。

生成する頻度でオーバーフローするカウンタを設定し、それを使用してウェーブテーブルのインデックスを作成し、DACの出力値を取得します。

Arduinoのいくつかの異なる音源技術をここにNew Noises From MidiVoxに書きました。 DACの更新コードはMidiVox(およびAdafruit WaveShieldの)MCP4921に固有ですが、正弦波の生成は一般に適用可能です。私はコードをほとんどATmegasに一般的に保ちようとしましたが、そこには2つのArduino-ismsが入り込んでいます。

MCP4921でArduinoで440Hzトーンを再生するコードがありますSPIバス上:

uint16_t sample = 0; 

/* incr = freq * (2^16/15625) 
* So for 440Hz, incr = 1845 */ 
uint16_t incr = 1845; 

/* oscillator position */ 
uint16_t pos = 0; 

const uint8_t sine[] = { 
    0x80, 0x83, 0x86, 0x89, 0x8C, 0x8F, 0x92, 0x95, 0x98, 0x9B, 0x9E, 0xA2, 
    0xA5, 0xA7, 0xAA, 0xAD, 0xB0, 0xB3, 0xB6, 0xB9, 0xBC, 0xBE, 0xC1, 0xC4, 
    0xC6, 0xC9, 0xCB, 0xCE, 0xD0, 0xD3, 0xD5, 0xD7, 0xDA, 0xDC, 0xDE, 0xE0, 
    0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEE, 0xF0, 0xF1, 0xF3, 0xF4, 
    0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 
    0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 
    0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF3, 0xF1, 
    0xF0, 0xEE, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 
    0xDA, 0xD7, 0xD5, 0xD3, 0xD0, 0xCE, 0xCB, 0xC9, 0xC6, 0xC4, 0xC1, 0xBE, 
    0xBC, 0xB9, 0xB6, 0xB3, 0xB0, 0xAD, 0xAA, 0xA7, 0xA5, 0xA2, 0x9E, 0x9B, 
    0x98, 0x95, 0x92, 0x8F, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 
    0x74, 0x71, 0x6E, 0x6B, 0x68, 0x65, 0x62, 0x5E, 0x5B, 0x59, 0x56, 0x53, 
    0x50, 0x4D, 0x4A, 0x47, 0x44, 0x42, 0x3F, 0x3C, 0x3A, 0x37, 0x35, 0x32, 
    0x30, 0x2D, 0x2B, 0x29, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18, 
    0x16, 0x15, 0x13, 0x12, 0x10, 0x0F, 0x0D, 0x0C, 0x0B, 0x0A, 0x08, 0x07, 
    0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 
    0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 
    0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x12, 0x13, 0x15, 
    0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29, 0x2B, 0x2D, 
    0x30, 0x32, 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x42, 0x44, 0x47, 0x4A, 0x4D, 
    0x50, 0x53, 0x56, 0x59, 0x5B, 0x5E, 0x62, 0x65, 0x68, 0x6B, 0x6E, 0x71, 
    0x74, 0x77, 0x7A, 0x7D 
}; 

void setup() { 
    cli(); 

    /* Enable interrupt on timer2 == 127, with clk/8 prescaler. At 16MHz, 
     this gives a timer interrupt at 15625Hz. */ 
    TIMSK2 = (1 << OCIE2A); 
    OCR2A = 127; 

    /* clear/reset timer on match */ 
    TCCR2A = 1<<WGM21 | 0<<WGM20; /* CTC mode, reset on match */ 
    TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20; /* clk, /8 prescaler */ 

    SPCR = 0x50; 
    SPSR = 0x01; 
    DDRB |= 0x2E; 
    PORTB |= (1<<1); 

    sei(); 
} 

ISR(TIMER2_COMPA_vect) { 
    /* OCR2A has been cleared, per TCCR2A above */ 
    OCR2A = 127; 

    pos += incr; 

    /* shift left a couple of bits for more volume */ 
    sample = sine[highByte(pos)] << 2; 

    PORTB &= ~(1<<1); 

    /* buffered, 1x gain, active mode */ 
    SPDR = highByte(sample) | 0x70; 
    while (!(SPSR & (1<<SPIF))); 

    SPDR = lowByte(sample); 
    while (!(SPSR & (1<<SPIF))); 

    PORTB |= (1<<1); 
} 

void loop() { 
} 

ダイレクトデジタル合成についての気の利いたことは、それが(添加によって)一緒に複数のトーンを再生したり(追加する前にボリュームを乗じて)希望ボリュームでそれらをミックスすることは非常に簡単だということです。

私はArduinoがこの方法を使って同時に約30音を演奏できることを発見しました。私の特定のアプリケーションはHammond organ simulationのためであり、それは有用な読書としても役立つかもしれません。

関連する問題