본문 바로가기

IT/Tizen

[Tizen] 타이젠 개발, Player API로 소리 재생해보기


안녕하세요, 타이젠 개발자 윤진입니다.


Tizen 개발자 사이트에 방문해 보면 개발에 참고할만한 자료들이 많습니다.

말로만 좋다고 해봐야 입에 발린 소리를 하는 것으로 비춰질지도 모르니,

이번 포스팅은 철저히 Tizen 개발자 사이트의 자료를 이용하도록 하겠습니다.



여기에 들어가보시면 상기 그림과 같은 드럼앱 작성법이 나와 있습니다.

드럼을 치면 그에 맞는 소리가 플레이되는 간단한 앱입니다.

위의 그림만 봐도 드럼앱을 개발하고 싶은 욕구가 솟아나오시지요? :)


소리를 재생하려면 Player API를 사용합니다.

Player는 다수의 API로 구성되어 있는데,

그 중 라이프 사이클과 관련된 함수가 가장 중요합니다.

- player_create(), player_destroy()

- player_prepare(), player_unprepare()

- player_start(), player_stop(), player_pause()

위의 함수들로 Idle, Ready, Playing, Paused 상태를 관리합니다.


Player 상태 다이어그램


player_create()에서 재생을 위한 핸들을 생성해주면 Idle 상태로 진입합니다.

핸들을 이용하여 player_prepare()를 하면 비로소 재생할 준비를 합니다.

재생 준비가 되면 Ready 상태에 이르게 되는데요,

player_start()로 Playing 상태로 바뀌고,

player_pause()로는 Paused 상태로 바뀌며,

player_stop()을 실행하면 다시 ready 상태가 됩니다.


Player 상태 변이


위에서 언급한 상태 다이어그램을 함수 측면에서 살펴볼 수도 있습니다.

표에서는 각각의 함수를 실행하기 전에 수행해야할 pre-state를 확인할 수 있습니다.

대부분의 함수가 sync로 동작하기 때문에 절차적 프로그래밍을 하면 됩니다.

player_prepare_async()만이 async인데요, 드럼앱에서는 따로 사용하지 않았습니다.


우선, player 핸들을 생성하여 준비하는 단계를 살펴보겠습니다.

총 9개의 드럼이 있기 때문에 각각의 소리를 재생하기 위해서 9개의 player 핸들을 생성해야합니다.


static void init_base_player(app_data *ad)
{
player_create(&ad->player1);
player_set_uri(ad->player1, "/opt/usr/apps/org.tizen.drums/res/sounds/ride.wav");
player_prepare(ad->player1);

player_create(&ad->player2);
player_set_uri(ad->player2, "/opt/usr/apps/org.tizen.drums/res/sounds/crash.wav");
player_prepare(ad->player2);

player_create(&ad->player3);
player_set_uri(ad->player3, "/opt/usr/apps/org.tizen.drums/res/sounds/tom2.wav");
player_prepare(ad->player3);

player_create(&ad->player4);
player_set_uri(ad->player4, "/opt/usr/apps/org.tizen.drums/res/sounds/hihat2.wav");
player_prepare(ad->player4);

player_create(&ad->player5);
player_set_uri(ad->player5, "/opt/usr/apps/org.tizen.drums/res/sounds/hihat1.wav");
player_prepare(ad->player5);

player_create(&ad->player6);
player_set_uri(ad->player6, "/opt/usr/apps/org.tizen.drums/res/sounds/tom1.wav");
player_prepare(ad->player6);

player_create(&ad->player7);
player_set_uri(ad->player7, "/opt/usr/apps/org.tizen.drums/res/sounds/floor.wav");
player_prepare(ad->player7);

player_create(&ad->player8);
player_set_uri(ad->player8, "/opt/usr/apps/org.tizen.drums/res/sounds/snare.wav");
player_prepare(ad->player8);

player_create(&ad->player9);
player_set_uri(ad->player9, "/opt/usr/apps/org.tizen.drums/res/sounds/bass.wav");
player_prepare(ad->player9);
}


위의 함수를 보시면, player_create()를 9번 수행한 것을 확인할 수 있습니다.

그리고 획득한 핸들로 player_set_uri()를 사용하여 재생할 파일 경로를 입력하였습니다.

"file://"와 같은 prefix를 넣지 않고 바로 절대경로를 입력하여도 동작합니다.

파일 경로까지 입력하였으니 이제 재생을 위한 준비를 할 차례입니다.

player_prepare()함수를 사용하여 sync로 재생 준비를 마칩니다.


void play_audio(player_h player)
{
player_state_e player_state;
player_get_state(player, &player_state);
if (player_state == PLAYER_STATE_PLAYING) {
player_stop(player);
}
player_start(player);
}


이제 드럼을 터치하면 재생을 할 차례입니다.

재생을 하기에 앞서 현재 재생 중인지 여부를 확인합니다.

player_get_state() 함수를 사용하여 현재 상태를 확인할 수 있습니다.



함수를 통해 총 5가지 상태 중 하나의 값을 얻어옵니다.

만약 이미 플레이 중이라면,

player_get_stop()으로 플레이를 멈춥니다.

그리고 다시 player_start()로 재실행을 합니다.


드럼마다 이벤트 영역을 설정하여 play_audio() 함수를 실행하도록 합니다.

총 9개의 드럼이 제각각의 소리를 내는 것을 확인할 수 있습니다.

9개의 이벤트 영역을 설정하는 방법도 흥미로우니,

시간이 허락한다면 한 번 소스를 살펴보는 것도 좋습니다.


player를 위해 할당받은 자원을 정리할 차례입니다.

9개의 핸들에 대해 아래 두 함수를 이용하여 정리작업을 합니다.


    player_unprepare(app->player1);
    player_destroy(app->player1);


이상 아주 간단한 player 사용법이었습니다.

player에는 이외에도 굉장히 다양한 기능이 있습니다.

시간이 허락한다면 좀 더 복잡한 앱의 소스를 분석해보는 시간을 가져보겠습니다.


그럼 좋은 하루 보내세요~

끝_



* References

https://developer.tizen.org/

https://developer.tizen.org/community/tip-tech/drums-tizen

https://developer.tizen.org/dev-guide/2.4.0/org.tizen.native.mobile.apireference/group__CAPI__MEDIA__PLAYER__MODULE.html