2014年2月23日日曜日

SONY MDR-V6 について

2年ほどメインのヘッドフォンとして愛用している SONY MDR-V6。

モニターヘッドフォンとして有名な MDR-CD900ST よりもリスニング向けに作られており、音質的には全く別物と考えて良い。

SONY スタジオヘッドホン MDR-V6 (国内未発売) 並行輸入品
ソニー
売り上げランキング: 28,343






このヘッドフォンの良い点は、低域の迫力。

トランスを聞いていると、キックの音が本当に心地よく響く。

コストも MDR-CD900ST より低め。


悪い点は、高域の解像度があまり良くないこと。

実際にモニタリングしていると、金物やボーカルのサ行、高域のノイズが聞こえないことが多々ある。

おそらく、聴感的に耳障りな高域の音を聞こえにくくしているのだろう。

そのため、モニター用途としては使いにくい。

しかし、このヘッドフォンで良曲を聞いた時にどのように響くか覚えてしまえばミキシングできないこともない (一応、別のヘッドフォンで高域の細部を確認するのがよい)


結論としては、MDR-V6 はリスニング用としてはオススメ。

2014年2月22日土曜日

Android::MediaPlayer による Audio player 用 SeekBar の実装

前回に引き続き,Android のオーディオ/ビデオ再生用クラス MediaPlayer を用いて簡単なオーディオプレーヤーを作成する.

今回は、音楽の再生位置を操作できるシークバーを実装を行う.

シークバーの機能を以下のように定義する.
  1. ユーザが自由に再生位置を操作できる
  2. 曲の再生に合わせてシークバーの再生位置を示すつまみが動く
音楽再生とシークバーで再生位置を追従するという2つの動作を同時に実行するために,シークバー追従用のスレッドを生成し,ハンドラによって周期的に再生位置を追従する.

スレッドのrunメソッドとシークバー用イベントリスナーは,インターフェイスとして実装する.

以下のコードでは、前回からの追加部分を赤色で示している.



import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends Activity implements OnClickListener, OnSeekBarChangeListener, Runnable{
private Button playBt;
private Button stopBt;
private MediaPlayer mediaPlayer;
private SeekBar seekBar;
private boolean running;
private Thread thread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playBt = (Button)findViewById(R.id.button1);
stopBt = (Button)findViewById(R.id.button2);
playBt.setOnClickListener(this);
stopBt.setOnClickListener(this);
mediaPlayer = MediaPlayer.create(this, R.raw.sample);
seekBar = (SeekBar)findViewById(R.id.seekBar1);  
seekBar.setProgress(0);
seekBar.setMax(mediaPlayer.getDuration());
seekBar.setOnSeekBarChangeListener(this);
running = true;
thread = new Thread(this);
thread.start();
}
// Run the thread using for seekBar
public void run(){
while(running){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendMessage(Message.obtain(handler, mediaPlayer.getCurrentPosition()));
}
}
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
seekBar.setProgress(msg.what);
}
};

public void stopRunning(){
running = false;
}
// SeekBar-control
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
;
}    
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mediaPlayer.seekTo(seekBar.getProgress());
}
// Start mediaPlayer
public void start(){
if (!mediaPlayer.isPlaying()){
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
mediaPlayer.start();
}
}
// Pause mediaPlayer
public void pause(){
mediaPlayer.pause();
}
// Stop mediaPlayer
public void stop(){
mediaPlayer.pause();
mediaPlayer.seekTo(0);
}
// Button-control
public void onClick(View v) {
switch(v.getId()){
case R.id.button1: // Play-button
start();
break;
case R.id.button2: // Stop-button
stop();
break;
}
}
// Key-control
    @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK || 
      keyCode == KeyEvent.KEYCODE_HOME){
    mediaPlayer.stop();
    mediaPlayer.release();
    stopRunning();
    finish();
           return true;
       }
       return false;
}
}

2014年2月21日金曜日

Android::MediaPlayer による Audio Player の実装

Android のオーディオ/ビデオ再生用クラス MediaPlayer を用いて簡単なオーディオ再生プログラムを作成する.

簡単化のため,機能は以下のように定義した.

  1. 再生/停止ボタンを実装
  2. Androidアプリ自体が再生するオーディオファイルをリソースとして持つ

1. に関しては,MediaPlayerの仕様上,pause()により一時停止し,seekTo()で先頭に戻すことで停止を実現している.

これは,stop()→prepare()で停止できないというレポートがあったためである.
参考: 適当えんじにあ( ´д`): Android サウンドの MediaPlayer.stop() の罠?

2. に関しては,今回は res/raw 以下の sample.mp3 というファイルを指定したため,"R.raw.sample"となっている.

ここは再生するファイルのパスに応じて変えればよいが,オーディオ/ビデオファイルは res/raw 以下に配置しなければならない.

もしAndroid端末ローカルのファイルやWeb上のファイルを参照する場合は setDataSource() を用いる。

前者はファイルパス、後者はURLを指定すれば再生できるはずだ。


import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{

private Button playBt;
private Button stopBt;
private MediaPlayer mediaPlayer;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

playBt = (Button)findViewById(R.id.button1);
stopBt = (Button)findViewById(R.id.button2);
playBt.setOnClickListener(this);
stopBt.setOnClickListener(this);

mediaPlayer = MediaPlayer.create(this, R.raw.sample);
}

// Button-control

public void onClick(View v) {
switch(v.getId()){
case R.id.button1:
if (!mediaPlayer.isPlaying())
mediaPlayer.start();
break;
case R.id.button2:
mediaPlayer.pause();
mediaPlayer.seekTo(0);
break;
}
}

//Key-control
    @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode==KeyEvent.KEYCODE_BACK || 
      keyCode==KeyEvent.KEYCODE_HOME){
    mediaPlayer.stop();
    mediaPlayer.release();
    finish();
           return true;
       }
       return false;
}
}

2014年2月20日木曜日

Androidアプリ開発 背景色の変更

Androidアプリの背景色を変えるには、res/layoutフォルダ以下に格納されている画面レイアウトファイル activity_main.xml に,

android:background="#xxxxxx"

と背景色の定義を追加すればよい.ここで,#xxxxxx は任意のカラーコードである.



また,背景色をグラデーションさせるにはグラデーションに関して定義されたxmlを新たに生成する.

例えば,res/drawable/bgcolor.xmlを生成し,

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:angle="0"
        android:startColor="#yyyyyy"
        android:endColor="#zzzzzz" />
</shape>

と記述する.ここで,#yyyyyy, #zzzzzz は任意のカラーコードである.

android:startColorは開始点のカラーコード、android:endColorは終点のカラーコードを指定する.

android:angleはグラデーション方向であり,

android:angle 開始点 終点
0
90
180
270

と反時計回りに指定する.

res/drawable/bgcolor.xmlを生成した後は res/layout/activity_main.xmlに,

android:background="@drawable/bgcolor.xml"

とbgcolor.xmlを読みこむように定義する.


Android::AudioTrack の play 関数における Memory leak について

Android開発において最も低レベルなオーディオ再生用クラスである AudioTrack

使っている内に,何回も再生 (play()) と停止 (stop(), pause()) を繰り返すと落ちることが分かった.

調査してみると、どうやら play() 実行の度にメモリを消費しているようだ.

また、SoundPool でも同様の症状が起こるらしい (未確認).


解決方法としては,
  1. play() を1回だけ実行
  2. 停止時にリソース解放
が考えられる.

1. に関しては、

1) スレッドを停止,2) ハンドラを利用,3) スレッドを (短時間スリープさせて) ビジーループ

のいずれかを停止の代替手段として実装すればよいはず.

foobar2000でYouTubeの音楽を聞く

foo_youtube: Home インストール方法はこちら:  Foobar2000:How to install a component メリットとしては、 1) foobar 上で Youtube の音楽を聞ける(スペクトラムアナライザーやスペクトログラムを見た...