반응형
개발중인 악기 앱 개발을 위해 소리를 각종 소리를 만들고, 합성하고, 분석하는 방법을 포스팅.
아래 코드는 합성된 소리를 재생한다.
먼저 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 |
더욱 좋은 정보를 제공하겠습니다.~ ^^