A simple musical instrument application using pressure and distance measuring sensors
Information
日本語版がこのページ下半分にあります!
Japanese version is available lower half of this page.
What is this?
Watch this video.
A very simple musical instrument application using pressure and distance measuring sensors.
Hardware
The uchiwa tone has very simple hardware.
- Microcontroller module : mbed LPC1768
- Pressure sensor : Interlink Electronics FSR400
- Distance measuring sensor : Sharp GP2Y0E03
The two sensor output goes into mbed, the pressure sensor controls the sound amplitude and distance controls frequency.
Sound waveform is stored on RAM in mbed. This waveform is played with those sensor parameters.
Output comes from DAC output of mbed, so the output becomes sound through external amplifier and speaker.
IMPORTANT
The distance measuring sensor GP2Y0E03 uses infra-red light reflection from objects.
In my case, for the reflecting object, I used "uchiwa (a Japanese fan)" is used.
Don't be so pessimistic, if you don't have the uchiwa.
It may be OK to use enough size of cardboard or something ;)
Software
Some customization can be done in software.
Key/Pitch
The key of this instrument is made as "C".
When you get the (reflecting object's) distance of the "C", all 3 LED1, LED2 and LED3 will be turned-ON. This is a mechanism to help the player who does not have perfect pitch like me ;)
This reference tone (key) can be changed by REFERENCE_TONE
which is set as an item from "Tone_list".
Pitch can be controlled also. Edit the frequency for "A" by REFERENCE_PITCH
.
enum Tone_list { Tone_A = 0, Tone_Ais, Tone_H, Tone_C, Tone_Cis, Tone_D, Tone_Dis, Tone_E, Tone_Eis, Tone_F, Tone_G, Tone_Gis, }; #define REFERENCE_TONE ((float)Tone_C) #define REFERENCE_PITCH 442.0
Frequency control direction
The distance measuring sensor output controls the frequency.
Default setting is it generates lower frequency when the distance is shorter.
If you need opposite direction of frequency control, set CONTROL_DIRECTION
as SHORT_HIGH.
#define SHORT_HIGH 0 #define SHORT_LOW 1 #define CONTROL_DIRECTION SHORT_LOW
Waveform
The uchiwa tone plays sound which is stored in RAM.
This waveform can be changed by selecting options.
The program calculates the waveform before start the instrument operation. The calculation is done in function of init()
calling waveform_generator()
.
Sin wave
The default setting is WAVEFORM_SIN
. That calculate sin wave.
By the way, if user press the pressure sensor strong, the amplitude becomes over 100%. The uchiwa tone handles this high amplitude situation as clipping, which becomes distortion.
Other waveform
WAVEFORM_SAWTOOTH
and WAVEFORM_CUSTOM_HARMONICS
options are available also. The WAVEFORM_SAWTOOTH may give different sound taste.
float waveform_generator( int i ) { #define WAVEFORM_SIN //#define WAVEFORM_SAWTOOTH //#define WAVEFORM_CUSTOM_HARMONICS
WAVEFORM_CUSTOM_HARMONICS
The WAVEFORM_CUSTOM_HARMONICS
gives you more options. The waveform is calculated with given parameters.
The waveform can be defined by each harmonics' (normalized) frequency, amplitude and phase.
The number of harmonics is arbitrary but if many harmonics are defined, it will take time.
#ifdef WAVEFORM_CUSTOM_HARMONICS typedef struct element_st { float frequency; float amplitude; float phase; } element; #define REF_AMPLITUDE 1.0 static element e[] = { { 1.0, REF_AMPLITUDE / 1.0, 0 * PI }, { 3.0, REF_AMPLITUDE / 3.0, 0 * PI }, { 5.0, REF_AMPLITUDE / 5.0, 0 * PI }, { 3.33333, REF_AMPLITUDE / 2.0, 0 * PI },// nonintegral harmonics }; float f; r = 0.0; for ( int x = 0; x < sizeof( e ) / sizeof( element ); x++ ) { f = e[ x ].frequency * 2.0 * PI * ((float)i / (float)N_SAMPLES); r += e[ x ].amplitude * cos( e[ x ].phase ) * sin( f ); r += e[ x ].amplitude * sin( e[ x ].phase ) * cos( f ); } #endif
Fully custom waveform
Of course you can make the waveform anything you want.
Fill up sample[16384]
array with one cycle of your waveform.
Tips
Playing in right frequency
In default setting, when the distance measuring sensor gets distance for reference tone, all 3 LED1, LED2 and LED3 will be turned-ON.
There is an option to indicate the distance in heptatonic scale intervals. If the code compiled with #define OPERATION_AID
, the LED, LED2 and LED3 will show the frequency is in those range (eighth note accuracy).
degree | sol-fa | LED1 | LED2 | LED3 |
---|---|---|---|---|
I | do | ON | off | off |
II | re | off | ON | off |
III | mi | ON | ON | off |
IV | fa | off | off | ON |
V | sol | ON | off | ON |
VI | la | off | ON | ON |
VII | si | ON | ON | ON |
Remark
- Thank you Takashi Matsuoka san for providing GP2Y0E03 library. I'm using Matsuoka-san's library with small tweaks for my purpose.
- "Uchiwa" Illustration by http://www.wanpagu.sakura.ne.jp/summer20.html
これはなに?
このビデオを御覧ください.
圧力,測距センサを使った非常に単純な楽器アプリケーションです.
ハードウェア
「うちわトーン」のハードウェアはとても単純です.
- マイコンモジュール : mbed LPC1768
- 圧力センサ : Interlink Electronics FSR400
- 測距センサ : Sharp GP2Y0E03
2つのセンサの出力をmbedに接続.圧力センサが振幅を,距離が周波数を制御します.
音声波形はmbed内のRAMに保存されます.この音声波形がセンサからのパラメータに従って再生されます.
mbedのDAC出力を外部のアンプとスピーカと通すことによって音にします.
重要
測距センサ:GP2Y0E03は対象物からの赤外線の反射を用います.
私の場合,「うちわ」をその反射させるモノとして使いました.
でもうちわが用意できなくても凹む必要はありません
厚紙などでその代用が可能です.
ソフトウェア
ソフトウェアによるカスタマイズが可能です.
キー/ピッチ
この楽器のキーは"C"にしてあります.
反射物(うちわ)を,その"C"の位置に持ってくると3個のLED,LED1,LED2,LED3が全て点灯します.これは私のような絶対音感の無い演奏者のために用意された仕組みです (^ ^;
この基準音(キー)はREFERENCE_TONE
を「Tone_list」内の別のアイテムに設定することで変更可能です.
ピッチも変更可能です.基準音Aの周波数をREFERENCE_PITCH
の値によって変更できます.
enum Tone_list { Tone_A = 0, Tone_Ais, Tone_H, Tone_C, Tone_Cis, Tone_D, Tone_Dis, Tone_E, Tone_Eis, Tone_F, Tone_G, Tone_Gis, }; #define REFERENCE_TONE ((float)Tone_C) #define REFERENCE_PITCH 442.0
周波数制御の方向
測距センサの出力で周波数が変わります.
デフォルト設定では測定された距離が近いほど低い音となります.
これを逆に設定するにはCONTROL_DIRECTION
をSHORT_HIGHに設定してください.
#define SHORT_HIGH 0 #define SHORT_LOW 1 #define CONTROL_DIRECTION SHORT_LOW
波形
うちわトーンではRAMに保存された音声を再生します.
波形はプション選択で変更可能です.
プログラムは楽器としての動作前に波形を計算します.計算はinit()
関数から呼び出されるwaveform_generator()
で行われます.
サイン波
WAVEFORM_SIN
がデフォルト設定となっています.サイン波を計算します.
ところで圧力センサを強く押すと振幅は100%を超えるようになっています.この場合,うちわトーンはクリッピング波形による歪んだ音を出力します.
その他の波形
その他WAVEFORM_SAWTOOTH
とWAVEFORM_CUSTOM_HARMONICS
が用意されています. WAVEFORM_SAWTOOTHを選択すると違う音色が楽しめます.
float waveform_generator( int i ) { #define WAVEFORM_SIN //#define WAVEFORM_SAWTOOTH //#define WAVEFORM_CUSTOM_HARMONICS
WAVEFORM_CUSTOM_HARMONICS (高調波カスタマイズ)
WAVEFORM_CUSTOM_HARMONICS
によって更にカスタマイズ可能です.波形は設定したパラメータを元に計算します.
この波形は高調波毎の(正規化した)周波数,振幅,位相で定義されます.
高調波の数は任意ですが,たくさん定義すると計算に時間がかかります.
#ifdef WAVEFORM_CUSTOM_HARMONICS typedef struct element_st { float frequency; float amplitude; float phase; } element; #define REF_AMPLITUDE 1.0 static element e[] = { { 1.0, REF_AMPLITUDE / 1.0, 0 * PI }, { 3.0, REF_AMPLITUDE / 3.0, 0 * PI }, { 5.0, REF_AMPLITUDE / 5.0, 0 * PI }, { 3.33333, REF_AMPLITUDE / 2.0, 0 * PI },// nonintegral harmonics }; float f; r = 0.0; for ( int x = 0; x < sizeof( e ) / sizeof( element ); x++ ) { f = e[ x ].frequency * 2.0 * PI * ((float)i / (float)N_SAMPLES); r += e[ x ].amplitude * cos( e[ x ].phase ) * sin( f ); r += e[ x ].amplitude * sin( e[ x ].phase ) * cos( f ); } #endif
完全カスタム波形
もちろん波形は自由に作成したものを使うこともできます.
配列sample[16384]
に一周期分の波形を保存ししてください.
ちょっとしたコツ
正確な周波数で演奏する
デフォルトの設定では,測距センサーの測定値が基準音を出すものになった時にLED1〜LED3が全て点灯するようになっています.
この他に7音階の距離を表示するオプションが用意されています. #define OPERATION_AID
を有効にしてコンパイルすると,周波数がそれぞれの範囲に入った時に,LED1〜LED3がそれを表示してくれます (1/8音精度).
degree | sol-fa | LED1 | LED2 | LED3 |
---|---|---|---|---|
I | do | ON | off | off |
II | re | off | ON | off |
III | mi | ON | ON | off |
IV | fa | off | off | ON |
V | sol | ON | off | ON |
VI | la | off | ON | ON |
VII | si | ON | ON | ON |
備考
- Takashi Matsuokaさん,GP2Y0E03ライブラリの提供,ありがとうございます.このプログラムでは,コードに少し変更を加えて使用しています.
- "うちわ"のイラストは,http://www.wanpagu.sakura.ne.jp/summer20.htmlこちらから拝借しました
- 部品は秋月電子さんで購入できます
- 圧力センサ : Interlink Electronics FSR400
- 測距センサ : Sharp GP2Y0E03
- アンプとスピーカは百均の「セリア」で揃えました.(この回路ではほとんど心配ありませんが)価格が安いので何か変な信号を入れたりして壊してしまっても精神的ダメージが少ないから安心です(´(ェ)`)
Revisions of main.cpp
Revision | Date | Message | Actions |
---|---|---|---|
9:fb5f6209a33b | 2015-06-09 | add comment. ref-tone indicator improvement | File Diff Annotate |
8:5af7a442e39a | 2015-06-09 | waveform synthesising option added | File Diff Annotate |
7:9522d9848470 | 2015-06-08 | some changes before publishing | File Diff Annotate |
6:0121755ba84b | 2015-05-12 | fixed: 3'20'' problem | File Diff Annotate |
5:bb232622e1fc | 2015-05-12 | test 3'40'' | File Diff Annotate |
4:c06860b7a4ea | 2015-05-12 | vital sign lamp | File Diff Annotate |
3:b72b559aaee0 | 2015-05-12 | control direction change | File Diff Annotate |
2:225f68a31496 | 2015-04-28 | test | File Diff Annotate |
1:86ac6f8d9713 | 2015-04-28 | test | File Diff Annotate |
0:cc77dd0427d8 | 2015-04-28 | test | File Diff Annotate |