加速度モニター
前回の実験を元に、簡易型MIDIシーケンサーを作成する予定でしたが、UIのデザインで行き詰まり作成を見送りました。
ケロミン(ケロミン パペット電子楽器ケロミンの子供 コケロミン Green PM101KAM
今回は、車を運転していて前後左右にかかる加速度をモニターできないかな?
と思い、「加速度モニター」を作成しまた。
英語名は、「G Monitor」です。
http://www.androlib.com/android.application.kero391-tool-g_monitor-zCjCw.aspx
アプリ名を日本語、英語で分けて登録したのが原因なのか、AndroLibには、英語の方しか登録されていませんてした。
アンドロイドマーケットには、しっかり日本語名のものも登録されています。
以下、アプリの紹介です
前後左右に掛かる加速度を表示するアプリです。
車に設置して、丁寧な運転の手助けに使用できます。
主な機能
・0点調整
設置した角度によって狂う0点を調整します。
・警告表示
設定した加速度を記録すると、背景色を赤にして警告します。
ということで今回は、ここまでです。
MIDIファイルの作成と再生
今回は、「AndroidでMIDIファイルを作成して、再生できないのかな?」と思いいろいろ実験してみました。
まず、MIDIファイルの作成からです。
Androidでのファイルの作成は、javaのFileOutputStreamクラスが使えるようです。
ファイルの作成される場所は、権限等で決まっているみたいで、/data/data/{アプリケーション名}/files/{ファイル名}となるようです。
ネットでMIDIのフォーマットを調べて、自分なりにクラスを作成してまとめました。
MIDIファイルの作成は、MediaPlayer クラスが使えるようです。
ただ、プログラムで作成したファイルを再生する場合は、直接ファイル名を指定する必要があります。
MediaPlayer .setDataSource(ファイル名) ファイル名を指定しても動きませんでした。
ファイル名をフルパス指定にしても、駄目だったため、MediaPlayer .setDataSource(FileInputStream)として動かしました。
どちらもインターフェースがあるのに、ファイル名を直接指定する方法が駄目なのは、不思議な気分です。
お試しで、カエルの歌を指定したテンポでMIDIファイルを作成し、作成したMIDIファイルを再生するプログラムを作成しました。
以降に、実行時の画面と、コードを記載しておきます。
※コードは、かなりテキトウです。
今回の実験は、ここまでです。
これを応用して何か作れないかな?と考えています。
package MakeMidiFile.app;
import java.io.FileInputStream;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MakeMidiFile extends Activity
implements OnClickListener {
private MediaPlayer mediaPlayer = null;
private EditText temppo_text;
private Button button_Play;
private Button button_Stop;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
temppo_text = (EditText)findViewById(R.id.EditText01);
temppo_text.setText("120");
button_Play = (Button) findViewById(R.id.Button01);
button_Play.setOnClickListener(this);
button_Stop = (Button) findViewById(R.id.Button02);
button_Stop.setOnClickListener(this);
}
private void createMidiFile()
{
MidiFileWriter midFile = new MidiFileWriter(getBaseContext());
try {
// MIDIファイル作成
midFile.CreateMidiFile("temp", 2, 480);
// トラックデータ作成
// テンポ設定
int tempo = Integer.valueOf(temppo_text.getText().toString());
midFile.setTempo(tempo);
// 音色設定:ピアノ
midFile.setProgramChange((byte)0x00, (byte)0x00);
midFile.closeTrackData();
// トラックデータ作成
// カエルの歌
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.D4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.D4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.E4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.E4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.F4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.F4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.E4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.E4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.D4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.D4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.E4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.E4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.F4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.F4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.G4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.G4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.A4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.A4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.G4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.G4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.F4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.F4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.E4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.E4, (byte)0x00);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.E4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_080), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_080), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.D4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_080), (byte)MidiFileWriter.NoteNo.D4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.D4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_080), (byte)MidiFileWriter.NoteNo.D4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.E4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_080), (byte)MidiFileWriter.NoteNo.E4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.E4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_080), (byte)MidiFileWriter.NoteNo.E4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.F4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_080), (byte)MidiFileWriter.NoteNo.F4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.F4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_080), (byte)MidiFileWriter.NoteNo.F4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.E4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.E4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.D4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.D4, (byte)0x00);
midFile.addNoteOn((byte)0, 0, (byte)MidiFileWriter.NoteNo.C4, (byte)0x7F);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.addNoteOn((byte)0, midFile.getNoteDeltaTime(MidiFileWriter.NoteTime.Note_040), (byte)MidiFileWriter.NoteNo.C4, (byte)0x00);
midFile.closeTrackData();
} catch (Exception e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
if (midFile != null)
{
// MIDIファイル作成完了
midFile.Release();
}
}
@Override
public void onClick(View v) {
if (v == button_Play) {
// 再生してなかったら
if (mediaPlayer == null) {
// midファイルの作成
createMidiFile();
// メディアプレイヤーの作成
FileInputStream fis = null;
mediaPlayer = new MediaPlayer();
try {
fis = new FileInputStream("/data/data/MakeMidiFile.app/files/temp.mid");
if (fis != null){
mediaPlayer.setDataSource(fis.getFD());
}
mediaPlayer.prepare();
} catch (Exception e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
// ループ再生の設定
mediaPlayer.setLooping(true);
}
if (!mediaPlayer.isPlaying())
{
// MediaPlayerの再生
mediaPlayer.start();
}
}
else if (v == button_Stop) {
// 再生してたら
if (mediaPlayer != null) {
// MediaPlayerの停止
mediaPlayer.stop();
try {
mediaPlayer.release();
mediaPlayer = null;
} catch (Exception e) {
}
}
}
}
}
package MakeMidiFile.app;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import android.content.Context;
public class MidiFileWriter {
private String FILE_ID = ".mid";
// M T h d
private byte[] HEADER_TAG = {0x4d,0x54,0x68,0x64};
private byte[] HEADER_DATA_LEN = {0x00,0x00,0x00,0x06};
private byte[] MIDI_FORMAT = {0x00,0x01};
// M T r k
private byte[] TRACK_TAG = {0x4d,0x54,0x72,0x6b};
private byte[] TRACK_END = {0x00,(byte)0xff,0x2f,0x00};
private FileOutputStream fos = null;
private Context context = null;
private ArrayList<TrackData> TrackDataList = new ArrayList<TrackData>();
private int quarterNoteDeltaTime;
//*************************************************************************
// コンストラクタ
//*************************************************************************
public MidiFileWriter(Context contxt)
{
context = contxt;
}
//*************************************************************************
// MIDIファイル作成
//*************************************************************************
public boolean CreateMidiFile(String fileName ,int trackNo ,int deltaTime) throws IOException
{
if (fos != null)
{
return false;
}
String flname = fileName+FILE_ID;
quarterNoteDeltaTime = deltaTime;
try {
// ファイル作成
fos = context.openFileOutput(flname, Context.MODE_WORLD_WRITEABLE);
// ヘッダ
fos.write(HEADER_TAG);
// データサイズ
fos.write(HEADER_DATA_LEN);
// データフォーマット
fos.write(MIDI_FORMAT);
// トラック数
byte work = (byte)((trackNo & 0x0000ff00) >> 8);
fos.write(work);
work = (byte)(trackNo & 0x000000ff);
fos.write(work);
// デルタタイム
work = (byte)((deltaTime & 0x0000ff00) >> 8);
fos.write(work);
work = (byte)(deltaTime & 0x000000ff);
fos.write(work);
} catch (FileNotFoundException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
// 後処理
Release();
return false;
}
return true;
}
//*************************************************************************
// テンポを設定
//*************************************************************************
public void setTempo(int tempo)
{
int tempoTime = 60000000 / tempo;
TrackData trackData = new TrackData();
trackData.length = 7;
trackData.data = new byte[7];
trackData.data[0] = (byte)0x00;
trackData.data[1] = (byte)0xff;
trackData.data[2] = (byte)0x51;
trackData.data[3] = (byte)0x03;
byte work = (byte)((tempoTime & 0x00ff0000) >> 16);
trackData.data[4] = work;
work = (byte)((tempoTime & 0x0000ff00) >> 8);
trackData.data[5] = work;
work = (byte)(tempoTime & 0x000000ff);
trackData.data[6] = work;
TrackDataList.add(trackData);
}
//*************************************************************************
// プログラムチェンジ
//*************************************************************************
public void setProgramChange(byte ch, byte no)
{
TrackData trackData = new TrackData();
trackData.length = 3;
trackData.data = new byte[4];
trackData.data[0] = (byte)0x00;
trackData.data[1] = (byte)(0xc0 | ch);
trackData.data[2] = (byte)no;
TrackDataList.add(trackData);
}
//*************************************************************************
// Trackデータ追加
//*************************************************************************
public void addTrackData(byte[] data, int length)
{
if (length <= 0)
{
return;
}
TrackData trackData = new TrackData();
trackData.length = length;
trackData.data = new byte[length];
for(int i = 0; i < length; i++)
{
trackData.data[i] = data[i];
}
TrackDataList.add(trackData);
}
//*************************************************************************
// ノートオン
//*************************************************************************
public void addNoteOn(byte chNo, int deltaTime, byte noteNo, byte velocity)
{
byte[] dltime = deltaTime(deltaTime);
int dataLen = dltime.length + 3;
byte data[] = new byte[dataLen];
for(int i = 0; i < dltime.length; i++)
{
data[i] = dltime[i];
}
data[dltime.length + 0] = (byte)(0x90 | chNo);
data[dltime.length + 1] = (byte)noteNo;
data[dltime.length + 2] = (byte)velocity;
addTrackData(data, dataLen);
}
//*************************************************************************
// Trackデータクローズ
//*************************************************************************
public void closeTrackData()
{
int dataLen = 4; // データ長 データ終端データサイズを初期値とする
for(int i=0; i < TrackDataList.size(); i++)
{
dataLen += TrackDataList.get(i).length;
}
try {
// Trackヘッダ
fos.write(TRACK_TAG);
// データサイズ
byte work = (byte)((dataLen & 0xff000000) >> 24);
fos.write(work);
work = (byte)((dataLen & 0x00ff0000) >> 16);
fos.write(work);
work = (byte)((dataLen & 0x0000ff00) >> 8);
fos.write(work);
work = (byte)(dataLen & 0x000000ff);
fos.write(work);
// Trackデータ展開
for(int i=0; i < TrackDataList.size(); i++)
{
for(int c=0; c < TrackDataList.get(i).length; c++)
{
fos.write(TrackDataList.get(i).data[c]);
}
}
// Track終端
fos.write(TRACK_END);
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
clearTrackData();
}
//*************************************************************************
// MIDIファイル作成完了
//*************************************************************************
public void Release()
{
if (fos != null)
{
return;
}
try {
fos.close();
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
fos = null;
}
//*************************************************************************
// 音符のデルタタイムを計算
//*************************************************************************
public int getNoteDeltaTime(double noteTime)
{
return (int)(quarterNoteDeltaTime * noteTime);
}
//*************************************************************************
// Trackデータクリア
//*************************************************************************
private void clearTrackData()
{
TrackDataList.clear();
}
//*************************************************************************
// デルタタイムの計算
//*************************************************************************
private byte[] deltaTime(int deltaTime)
{
int size = 1;
if (deltaTime >= 0x00200000)
{
size = 4;
}
else if (deltaTime >= 0x00004000)
{
size = 3;
}
else if (deltaTime >= 0x00000080)
{
size = 2;
};
byte[] dltTime = new byte[size];
if (dltTime == null)
{
return null;
}
int workDeltaTime = deltaTime;
for(int i=(size-1); i >= 0; i--)
{
byte work = (byte)(workDeltaTime & 0x0000007f);
dltTime[i] = (byte)(work | 0x80);
workDeltaTime -= work;
workDeltaTime >>= 7;
}
dltTime[(size-1)] = (byte)(dltTime[(size-1)] & 0x7f);
return dltTime;
}
//*************************************************************************
// Trackデータ
//*************************************************************************
protected class TrackData
{
protected int length = 0;
protected byte[] data;
}
//*************************************************************************
// 音符
//*************************************************************************
public class NoteTime {
public final static double Note_010 = 4; // 全音符
public final static double Note_020 = 3; // 付点2分音符
public final static double Note_030 = 2; // 2分音符
public final static double Note_035 = 1.5; // 付点4分音符
public final static double Note_040 = 1; // 4分音符
public final static double Note_045 = 0.75; // 付点8分音符
public final static double Note_080 = 0.5; // 8分音符
public final static double Note_160 = 0.25; // 16分音符
}
//*************************************************************************
// ノートナンバー
//*************************************************************************
public class NoteNo {
public final static int C0 = 12;
public final static int CC0 = 13;
public final static int D0 = 14;
public final static int DD0 = 15;
public final static int E0 = 16;
public final static int F0 = 17;
public final static int FF0 = 18;
public final static int G0 = 19;
public final static int GG0 = 20;
public final static int A0 = 21;
public final static int AA0 = 22;
public final static int B0 = 23;
public final static int C1 = 24;
public final static int CC1 = 25;
public final static int D1 = 26;
public final static int DD1 = 27;
public final static int E1 = 28;
public final static int F1 = 29;
public final static int FF1 = 30;
public final static int G1 = 31;
public final static int GG1 = 32;
public final static int A1 = 33;
public final static int AA1 = 34;
public final static int B1 = 35;
public final static int C2 = 36;
public final static int CC2 = 37;
public final static int D2 = 38;
public final static int DD2 = 39;
public final static int E2 = 40;
public final static int F2 = 41;
public final static int FF2 = 42;
public final static int G2 = 43;
public final static int GG2 = 44;
public final static int A2 = 45;
public final static int AA2 = 46;
public final static int B2 = 47;
public final static int C3 = 48;
public final static int CC3 = 49;
public final static int D3 = 50;
public final static int DD3 = 51;
public final static int E3 = 52;
public final static int F3 = 53;
public final static int FF3 = 54;
public final static int G3 = 55;
public final static int GG3 = 56;
public final static int A3 = 57;
public final static int AA3 = 58;
public final static int B3 = 59;
public final static int C4 = 60;
public final static int CC4 = 61;
public final static int D4 = 62;
public final static int DD4 = 63;
public final static int E4 = 64;
public final static int F4 = 65;
public final static int FF4 = 66;
public final static int G4 = 67;
public final static int GG4 = 68;
public final static int A4 = 69;
public final static int AA4 = 70;
public final static int B4 = 71;
public final static int C5 = 72;
public final static int CC5 = 73;
public final static int D5 = 74;
public final static int DD5 = 75;
public final static int E5 = 76;
public final static int F5 = 77;
public final static int FF5 = 78;
public final static int G5 = 79;
public final static int GG5 = 80;
public final static int A5 = 81;
public final static int AA5 = 82;
public final static int B5 = 83;
public final static int C6 = 84;
public final static int CC6 = 85;
public final static int D6 = 86;
public final static int DD6 = 87;
public final static int E6 = 88;
public final static int F6 = 89;
public final static int FF6 = 90;
public final static int G6 = 91;
public final static int GG6 = 92;
public final static int A6 = 93;
public final static int AA6 = 94;
public final static int B6 = 95;
public final static int C7 = 96;
public final static int CC7 = 97;
public final static int D7 = 98;
public final static int DD7 = 99;
public final static int E7 = 100;
public final static int F7 = 101;
public final static int FF7 = 102;
public final static int G7 = 103;
public final static int GG7 = 104;
public final static int A7 = 105;
public final static int AA7 = 106;
public final static int B7 = 107;
public final static int C8 = 108;
public final static int CC8 = 109;
public final static int D8 = 110;
public final static int DD8 = 111;
public final static int E8 = 112;
public final static int F8 = 113;
public final static int FF8 = 114;
public final static int G8 = 115;
public final static int GG8 = 116;
public final static int A8 = 117;
public final static int AA8 = 118;
public final static int B8 = 119;
public final static int C9 = 120;
public final static int CC9 = 121;
public final static int D9 = 122;
public final static int DD9 = 123;
public final static int E9 = 124;
public final static int F9 = 125;
public final static int FF9 = 126;
public final static int G9 = 127;
}
}
これでも楽器です!
実装したのは、矩形波(従来の音)とノコギリ波 のみなので、まだまだ公開は先になりそうです。
なので今回は、大好きな楽器についてです。
↓の写真、何に見えるでしょうか?

ただのカエルのぬいぐるみに見えますが、楽器です。
左の小さい方は、コケロミン、右の大きい方は、ケロミンです。
両方ともパペット型の楽器で、カエルの口の開き具合で音程を決めます。
手をパペットの中に入れて、口を操作します。
普通の楽器を扱った事がない人でも、ある程度すぐに弾けるようになります。
値段ですが、ケロミンは、5万ほどと見かけとは違って可愛くないですが、コケロミンは、1万ほどとお手ごろな値段です。
下にリンクを張っておきますので、興味のある方は、見てください。
本日は、このあたりでおしまいです。
楽器アプリを作ってみよう!⑤
あれから、コソコソとバージョンアップを繰り返していました。
設定画面を変更したり、音の出る範囲を C3~C6 の間で設定できるように拡張しました。
最下音と最高音を同じ音に設定すると、1音のみ鳴ります。
複数台の端末それぞれ違う音程を設定すると、ハンドベルみたいな使い方をできます^^
最近デバック機として↓のハードを購入しました。
![]() | Android2.2搭載Smart Phone/IDEOS with Google/SimフリーSmart Phone () HUAWEI IDEOS 商品詳細を見る |
なかなか使いやすく重宝しています。
値段もお手ごろなのでほぼ衝動買に近かったですが^^;
現在、出せる音色を増やそうと格闘しております。
1データあたり8ビットの設定にしているのですが、複雑な波形を出力しようとすると音が潰れるようです。
しっかり実装しようとすると、16ビットに変更する必要がありそうです。
まぁ マイペースでバージョンアップしていきたいと思います。
楽器アプリを作ってみよう!④
http://jp.androlib.com/android.application.kero391-music-easymusic-qwpnD.aspx
どんなアプリかというと
名前「Easy Music」
端末左右に傾ける事で音程が変わり、画面にタッチすると発音します。
画面のタッチ位置によって音程が変わったり、ボリュームも変わるようにできます。
音階として、半音階、ハ長調、ブルーノート、琉球音階を選ぶ事ができます。
傾けて音程決めるので、雑に扱うと音程が...となりますが、琉球音階なんか使うと、それなりに沖縄音楽っぽくなります^^
今後、音階の種類を増やしたり、少し機能拡張したりしていく予定です。









