개발중인 악기 앱 개발을 위해 소리를 각종 소리를 만들고, 합성하고, 분석하는 방법을 포스팅.
아래 코드는 합성된 소리를 재생한다.
먼저 Layout 파일을 보면
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/StartSound"
android:text="Start Sound"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/EndSound"
android:text="End Sound"/>
</LinearLayout>
스타트, 스톱을 실행하는 버튼 2개를 배치한다.
코드를 살펴보면 onCreate 에서 버튼 등록하고 리스너를 등록해준다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_main);
startSound = (Button) this.findViewById(R.id.StartSound);
startSound.setOnClickListener(this);
endSound = (Button) this.findViewById(R.id.EndSound);
endSound.setOnClickListener(this);
endSound.setEnabled(false);
}
클릭할떼 어느 버튼인지 알아서 실행해주고
public void onClick(View v) {
if (v == startSound) {
keepGoing = true;
audioSynth = new AudioSynthesisTask();
audioSynth.execute();
endSound.setEnabled(true);
startSound.setEnabled(false);
} else if (v == endSound) {
keepGoing = false;
endSound.setEnabled(false);
startSound.setEnabled(true);
}
}
실제 여기가 가장 중요한 부분으로 AsyncTask 를 확장하는 내부 클래스 AudioSynthesisTask 를 만들어준다.
AsyncTask<Void, Void, Void> 에는 doInBackground(Void... params) 라는 메소드가 정의되어 있고, 이 메소드는 액티비티의
메인스레드와는 별도의 스레드로 무엇이든 실행해준다.
private class AudioSynthesisTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
final int SAMPLE_RATE = 11025;
int minSize = AudioTrack.getMinBufferSize(SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minSize,
AudioTrack.MODE_STREAM);
audioTrack.play();
short[] buffer = {
8130, 15752, 32695, 12253, 4329,
-3865, -19032, -32722, -16160, -466,
8130, 15752, 22389, 27625, 31134, 32695, 32210,
29711, 25354, 19410, 12253, 4329, -3865, -11818, -19032,
-25055, -29511, -32121, -32722, -31276, -27874, -22728,
-16160, -8582, -466
};
/*short[] buffer = {
8130, 15752, 32695, 12253, 4329,
-3865, -19032, -32722, -16160, -466
};*/
/*
short[] buffer = { 8130, 15752, 22389, 27625, 31134, 32695, 32210,
29711, 25354, 19410, 12253, 4329, -3865, -11818, -19032,
-25055, -29511, -32121, -32722, -31276, -27874, -22728,
-16160, -8582, -466 };
*/
while (keepGoing) {
audioTrack.write(buffer, 0, buffer.length);
}
return null;
}
}
윗부분은 오디오 트랙 설정하는 부분이고, 오디오 트랙을 실행시키고 오디오 트랙에 출력할 "소리데이터"를 계속 써주면 "소리"가 재생된다.
지금 그 소리를 찾고 있다.
전체 코드를 몽땅 아래에 올립니다.
package com.soriedu.audiosynth02;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class AudioMainActivity extends Activity implements OnClickListener {
Button startSound;
Button endSound;
AudioSynthesisTask audioSynth;
boolean keepGoing = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_main);
startSound = (Button) this.findViewById(R.id.StartSound);
startSound.setOnClickListener(this);
endSound = (Button) this.findViewById(R.id.EndSound);
endSound.setOnClickListener(this);
endSound.setEnabled(false);
}
@Override
public void onPause() {
super.onPause();
keepGoing = false;
endSound.setEnabled(false);
startSound.setEnabled(true);
}
public void onClick(View v) {
if (v == startSound) {
keepGoing = true;
audioSynth = new AudioSynthesisTask();
audioSynth.execute();
endSound.setEnabled(true);
startSound.setEnabled(false);
} else if (v == endSound) {
keepGoing = false;
endSound.setEnabled(false);
startSound.setEnabled(true);
}
}
private class AudioSynthesisTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
final int SAMPLE_RATE = 11025;
int minSize = AudioTrack.getMinBufferSize(SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minSize,
AudioTrack.MODE_STREAM);
audioTrack.play();
short[] buffer = {
8130, 15752, 32695, 12253, 4329,
-3865, -19032, -32722, -16160, -466,
8130, 15752, 22389, 27625, 31134, 32695, 32210,
29711, 25354, 19410, 12253, 4329, -3865, -11818, -19032,
-25055, -29511, -32121, -32722, -31276, -27874, -22728,
-16160, -8582, -466
};
/*short[] buffer = {
8130, 15752, 32695, 12253, 4329,
-3865, -19032, -32722, -16160, -466
};*/
/*
short[] buffer = { 8130, 15752, 22389, 27625, 31134, 32695, 32210,
29711, 25354, 19410, 12253, 4329, -3865, -11818, -19032,
-25055, -29511, -32121, -32722, -31276, -27874, -22728,
-16160, -8582, -466 };
*/
while (keepGoing) {
audioTrack.write(buffer, 0, buffer.length);
}
return null;
}
}
}
'개발자 > Android' 카테고리의 다른 글
| import android.support.v4.app.NotificationCompat; 에러 해결법 (0) | 2015.02.03 |
|---|---|
| Can't Find Theme.AppCompat.Light (0) | 2015.01.08 |
| 안드로이드 ApiDemo PrintHelper error 문제 (1) | 2014.09.22 |
| audacity 를 사용해서 리코더 음원을 분석하는 중 (0) | 2013.03.22 |
| 안드로이드 일정한 톤으로 사운드 생성 하고 플레이 - (4) | 2013.03.13 |
| 안드로이드 AudioRecoder 쓸때 에러메시지 - 퍼미션 줘야 됨. (3) | 2013.02.28 |
| 한 프로젝트 다른 패키지의 액티비티 실행할때 매니패스트에 경로입력 (0) | 2013.02.26 |
| 안드로이드 스트링 비교시 주의 할 점~ 알파벳 첫글자 비교등과 같은... (0) | 2013.01.10 |
취업, 창업의 막막함, 외주 관리, 제품 부재!
당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약,
아이디어는 있지만 구현할 기술이 없는 막막함.
우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.
이제 고민을 멈추고, 캐어랩을 만나세요!
코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.
제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!
귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.
지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.
귀사가 성공하기까지의 긴 고난의 시간을 캐어랩과 함께 하세요.
캐어랩