본문 바로가기

개발자/Android

안드로이드 악기 앱 개발을 위한 AudioTrack 사용하기

반응형



개발중인 악기 앱 개발을 위해 소리를 각종 소리를 만들고, 합성하고, 분석하는 방법을 포스팅.


아래 코드는 합성된 소리를 재생한다.


먼저 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;
		}
	}

	
}




반응형

캐어랩 고객 지원

취업, 창업의 막막함, 외주 관리, 제품 부재!

당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약, 아이디어는 있지만 구현할 기술이 없는 막막함.

우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.

이제 고민을 멈추고, 캐어랩을 만나세요!

코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.

제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!

귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.

지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.

카카오 채널 추가하기

카톡 채팅방에서 무엇이든 물어보세요

귀사가 성공하기까지의 긴 고난의 시간을 캐어랩과 함께 하세요.

캐어랩 온라인 채널 바로가기

캐어랩