素人のアンドロイドアプリ開発日記

音のコンテンツ

MediaRecorder周りで少し改善する。

2012.05.26

今回はMediaRecoreder周りで少し、自分でわかった事があったので、

音声を使って楽しげなものを作りたい。簡単な録音

で書いていた分でしたが、今回はちょっとプラスで書かせてもらいます。

 

■mp3に変換したい

mp3という形式が一般には有名で、多くの人もこの形式を望んだりしますが、この形式にするには現状のアンドロイドではデフォルトで用意されていません。

いろいろなサイトをみた結果、一応、音のデータを取得して、劣化なしのwavの形式などにできるので、そのwavのまま、NDKという、c#が使える方法があるのですが、ネイティブコードと結構表現されたりしますが、

c#ではwav形式をmp3に変換するライブラリがあって、それを利用しましょう。っていうのが、現在のところ、唯一の方法でした。mp3に変換するjavaのライブラリもありそうですが、音関係の情報は一般的に多くなくわりと大変でした。

なので、僕はあきらめました。この報告ですが、割りと探せばありそうな気がしたので、1日を無駄にして、この結論に至ったとの報告です。

絶対な条件だったり、ndkに親和性があればやってもいいかな。とおもいます。

 

■音質が悪い。

次ですが、以前の方法で、音を取得していたのですが、どうも音質が悪い。

recorder.setAudioSamplingRate

という関数がandroidの2.2~で利用ができるのですが、ここの値が8000だと大丈夫ですが、44100にするとエラーで落ちてしまいました。

というか、デフォルトの値は8000だから音質が悪い。という感じもしますが、ここの値を変更する際には、

recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

のようにencoderをDEFAULTにしていたのをAACに変更してあげます。

そうすると、エラーも起きないで、高音質な録音が可能でした。

一応、8000,16000,22050,44100あたりが標準でサポートされてくれる値なので、44100で容量が重くなってしまうなどで、懸念があれば、22050あたりで音質を少し減らしてもいいと思います。

 

自分で実際に試したところ、音質の違いが大きすぎてびっくりしました。

ぜひ、お試しください。

 

 

カテゴリー:

音声を使って楽しげなものを作りたい。簡単な再生

2011.06.17

前回はデータをそのままの形で保存してそのままのを取得して出力をしていましたが、

前々回に作成したような

音声を使って楽しげなものを作りたい。簡単な録音

で作成したファイル(.3gp)とかに関しての再生方法も説明します。

※バッファーを使うものと平行に勉強してしまいすいません。。

 

MediaPlayerクラスを利用します。

MediaPlayerに対応する主な形式は
.3gp,mp4,mp3,.ogg,.wavなど、です。

Tech Booth

で再生方法を参照しました。

MediaPlayer mp = MediaPlayer.create(this, R.raw.music);
mp.start();

のみ。との事で、rawファイルの中にいれた音楽のデータを再生する事ができるようです。

rawファイルはresディレクトリの直下に配置をする必要があります。

private MediaPlayer mp;

MediaPlayer mp = new MediaPlayer();
mp.setDataSource("***.wav");
mp.prepare();
mp.start()

データまでのパスを記載する事で、音楽を流す事ができます。

android developpers

pauseやstopなども用意されているようなので、割と間隔で利用できるクラスのようです。

prepare周辺でエラーが発生する場合には、MediaPlayer.OnPreparedListenerでprepareの完了をまって、startをするとエラー回避できるようです。

カテゴリー:

音声を使って楽しげなものを作りたい。再生をする。

2011.06.16

今回は

音声を使って楽しげなものを作りたい。録音をする。

で録音した音を再生したいと思います。

 

バッファーを利用してロードした音のデータを再生します。

今回の方法に関しても、音のデータをいじる為にバッファを利用していますが、

単純に録音及び再生にはMediaRecorder,MediaPlayerを利用するのが楽だと思います。

※MediaPlayerに関しては、また今度紹介します。

 

保存されたデータに関しては、取得方法もいろいろあると思いますが、

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/sound.pcm");

のパスのデータが存在する状態ではじめたいと思います。(実際に利用する場合には、exist()などを利用して、存在を確かめる方が確実です。)

この値を取得する時のStreamを作成します。

InputStream is = new FileInputStream(file);

この値をバッファー単位で取得できるようにします。

BufferedInputStream bis = new BufferedInputStream(is);

このバッファーからバイト配列をデータに変換する必要があるので、

DatainputStream dis = new DataInputStream(bis);

とする事で、ファイル取得の方法ができました。

また、中に含まれているデータに関しては16bitのデータである
(8bitだとエラーが発生したので。。)

ファイルの長さの半分の長さだけのデータが含まれているかと思いますので、

int musicLength = (int)(file.length()/2);
short[] music = new short[musicLength];

です。

 

ファイルの中のデータをmusicの中に移します。

int i = 0;
while(dis.available() > 0){
 music[i] = dis.readShort();
 i++;
}

※申し訳ありません。音を逆再生設定してしまっておりましたので、修正します。

取り出し終えた段階で、ファイルの方はcloseをします。

dis.close();

また、上で取得したデータを再生する為に、AudioTrackクラスを作成します。

AudioTrack audioTrack = new AudioTrack(
 AudioManager.STREAM_MUSIC,
 44100,
 AudioFormat.CHANNEL_CONFIGURATION_MONO,
 AudioFormat.ENCODING_PCM_16BIT,
 musicLength,
 AudioTrack.MODE_STREAM);

上記のようにバッファーサイズに関しては、音楽の長さ分いれているのですが、
要するに、音楽を流す準備ができたら流し始めるという設定をしています。

先にplayをしておきます。

audioTrack.play();

playの後に中に入れるデータを用意するには少し変な感じですが、STREAMって要はこういう事なのかと。。
このaudioTrackの中にデータをいれるとバッファーを満たした段階で再生されます。

audioTrack.write(music, 0 ,musicLength);

以上でバッファーが溜まり次第、音楽が再生される仕様を作成しました。

 

カテゴリー:

音声を使って楽しげなものを作りたい。簡単な録音

2011.06.16

前回にバッファーを利用して、録音する方法を勉強しましたが、

音声を使って楽しげなものを作りたい。録音をする。

今回は簡単に録音をする方法を勉強してみます。

 

MediaRecorderクラスを利用します。

MediaRecorder mediaRecorder = new MediaRecorder();

最初に入力のソースを設定します。

mediaRecorder.serAudioSource(MediaRecorder.AudioSource.MIC);

Android developpers

に記載されていますが、基本的に通話中の音声を取得するかマイクを利用する形です。今回はマイクを選択します。

次に出力のフォーマットを設定します。

mediaRecorder.serOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

でここで指定できるフォーマットの形は以下になります。

AMR_NB         AMR NB file format
AMR_WB         AMR WB file format
DEFAULT     
MPEG_4         MPEG4 media file format
RAW_AMR     AMR NB file format
THREE_GPP     3GPP media file format

上記の形式ですが、確認してみます。

AMR_NB:AMRは音声に特化したもので、圧縮率は高いが音質は劣る。

AMR_WB :AMRを発展させた形式でマルチレートの広帯域音声符号化方式

MPEG_4:mpegは動画などにも応用できる形式割と汎用性の高い形式。

3GPP:3GPPファイルフォーマットは、主にMMS(日本でいう写メールやiショットに相当)で動画や音声をメールで送信するために利用される。

ですが、一般的には、3GPPを用いる場合が多いようです。メール送信を視野に入れた場合にも有用な形式なので、よほどの理由がなければ3GPPが推奨です。

 

次の音声のエンコーダーを設定します。

mediaRecorder.setAudioEncoder(MediaRecoder.AudioEncoder.DEFAULT)

Android developpersで記載されているのは以下の形式です。

AAC         AAC audio codec
AMR_NB         AMR (Narrowband) audio codec
AMR_WB         AMR (Wideband) audio codec
DEFAULT

特にDEFAULTでも問題ないと思いますが、音質に疑問が出たらエンコーダーをいじるのも手だと思います。

 

上記の設定をしたら画像を保存するパスを指定します。

mediaRecorder.setOutputPath(***/***.3gp)

かなり割愛してしまいましたが、必要に応じて、ディレクトリを作成したりする必要があります。

 

ここまでできれば残りは簡単な操作のみです。

準備をします。
mediaRecorder.prepare();
開始をします。
mediaRecorder.start();
停止をします。
mediaRecorder.stop();
開放をします。
mediaRecorder.release();

データを作成した後に他のアプリケーションで利用する場合にはandroidのデータベースにアクセスする必要もありそうです。

 

また、マニフェストには下記の2つの設定が必要になります。

android.permission.RECORD_AUDIO
android.permission.WRITE_EXTERNAL_STORAGE

カテゴリー:

音声を使って楽しげなものを作りたい。録音をする。

2011.06.16

音を保存したい時にmediaRecorderクラスと言う、保存に便利なクラスが存在しますが。。

(mediaRecorderについては次あたりに紹介します。)

楽しげなものを作りたいので、今回は生のデータをそのままで保存をしてみたいと思います。

 

参考:Raw Audio Manipulation in Android

 

audioRecordクラスを利用します。

初期設定としては

private static final int SOUND_RATE = 44100;
int bufferSizeRecord = AudioRecord.getMinBufferSize(SOUND_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,SOUND_RATE,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,bufferSizeRecord)

上記の設定で音の取得の準備が完了しました。

実行は次の関数です。

short[] bufferRecord = new short[bufferSizeRecord];
audioRecord.startRecoding();

上記で、実行の準備ができました。
次の実際にデータが入ってきた場合の対応をしましょう。

int bufferReadResult = audioRecord.read(bufferRecord,0,bufferSizeRecord);

でbufferRecordの中に配列として、読み込まれたデータが格納されています。

ここで、データの保存の方法ですが、
一時的に保存できる領域が限られているので、SDcardの中に読み込みができる領域を作成します。

尚、この時に保存する形式は今回はpcmと言う保存形式にします。
(非圧縮の形式です。)

もしも、保存できるようにする場合などはディレクトリを作成してもよいかもしれませんが、
今回は、一時保存の領域の為にSDcard直下に作成をします。

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/sound.pcm");

このファイル自体は存在していた場合には上書きの手間がかかるので、
存在する場合には、削除してしまいます。

if(file.exist()){
 file.delete();
}

次の新しいファイルを作成します。

file.createNewFile();

このファイルに関しての出力部分でのStreamを作成します。

OutputStream os = new FileOutStream(file);

AndroidのFile入出力サンプル

上記のサイトによると、FileOutStreamは書き込み用のStreamのようです

 

今回は高速で書き込む必要があるので、このFileOutStream()をbufferに対応できるように変換する。

BufferedOutputStream bos = new BufferOutputStream(os);

このバッファーアウトプットクラスを使う事で、1byteづつではなくバッファーごとに書き込みができるようになるので、一度に入力できるようになりました。

バッファ入出力

このデータに入れる段階で、音のデータに関しては各々が数値のデータとして取得されているので
バイトに変換できるようにDataOutputStreamとして利用をする必要があります

ByteArrayOutputStream,DataOutputStream – 数値をバイト配列に変換する

DataOutputStream dos = new DataOutputStream(bos);

とします。これで、書き込みができるようになりました。

先ほど作成した、bufferのデータに関してはbufferReadResultの数だけ、書き込みます。

for(int i = 0 ; i < bufferReadResult ; i++){
 dos.writeShort(buffer[i]);
}

でデータへの書き込みが行えるようになりました。

全てのデータの書き込みが完了した段階で、

audioRecord.stop();
dos.close()

を行いましょう。

上記には説明の簡単の為、割愛させていただいておりましたが、
threadの内部で実行をするイメージです。

while(recording){
 int bufferReadResult = audioRecord.read(bufferRecord,0,bufferSizeRecord);
 for(int i = 0 ; i < bufferReadResult ; i++){
 dos.writeShort(bufferRecord[i]);
 }
}

この段階では非圧縮のデータの保存のみなので、
次回、保存したデータの再生方法、また、圧縮形式での保存方法を少し勉強する予定です。

中途半端な感じですが、次回につながる内容にしてみました。

カテゴリー:

公開中のアプリ、是非ダウンロードしてみてください

2chまとめのたね

RSSを利用してさまざまなブログの情報をキュレーションしてくれるアプリ

インストールする

ひらがな戦記

OPENGL ES2 を利用したカルタのソーシャルゲーム

インストールする