Drums for Tizen

“Drums for Tizen” is a simple and fun app that allows the user to play on a virtual drum kit.

This app makes use of the Player API, which plays a selected sound, when the user touches a specified place on the screen, corresponding to the drums on screen.

Step by step introduction

This app is not a very complicated one however it is not trivial either. What we want to achieve is first to read sound files into memory then be able to play them. The next step is to setup a touch (MOUSE_DOWN) listener and setup different sounds for when the user touches in different places.

Playing sound files

The first thing we do is set up an object of player_h type. We are going to need one for each different sound we are going to play. To use it, we need to include the player.h file.

#include <player.h>
player_h player1, player2, player3, player4, player5, player6, player7, player8, player9;

The next thing to do is attach a sound file to the previously created player.

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

All the sound files have been put in the res/sounds folder. It can be accessed by using the above address. The first part ( “/opt/usr/apps/”) is default, what follows is the package name (same as in the manifest) and the path to the file.

Now that we have the sound files attached to player objects, we want to play them. This is taken care of by the following method:

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);
}

If the player is currently playing and we want the same sound to be played again in quick succession, we make it stop playing and restart it quickly.

Coming together

Once we’ve achieved playing of audio files, we should attach a background, so the user knows what drum/cymbal he wants to be played.

ad->bg = elm_bg_add(ad->win);
evas_object_size_hint_weight_set(ad->bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
snprintf(buf, sizeof(buf), "%s/background.png", ICON_DIR);
elm_bg_file_set(ad->bg, buf, NULL);
elm_win_resize_object_add(ad->win, ad->bg);
evas_object_show(ad->bg);

We also need to attach a MOUSE_DOWN callback, so we know when the background is being touched and where.

evas_object_event_callback_add(ad->bg, EVAS_CALLBACK_MOUSE_DOWN, mouse_down_cb, ad);

We obviously need a nice background to achieve a positive effect.

We now need to calculate which position corresponds to which sound, and unfortunately this data has to be inserted by hand.

      drum __pRide = { 216, 1187, 556 };
      drum __pCrash = { 216, 887, 648 };
      drum __pTom = { 167, 260, 405 };
      drum __pTom2 = { 170, 605, 478 };
      drum __pHihat2 = { 157, 242, 680 };
      drum __pHihat = { 157, 48, 550 };
      drum __pFloor = { 190, 888, 223 };
      drum __pSnare = { 200, 512, 156 };
      drum __pBass = { 230, 178, 157};

The structure above contains 3 integer values: the drum/cymbal radius, its x and y position. To verify whether a drum has been touched, we need to compare the radius to the distance from the touch.

static float
get_distance(int x1, int y1, int x2, int y2) {
      int rx = (x2 - x1);
      int ry = (y2 - y1);
      rx *= rx;
      ry *= ry;
      int dist = (rx + ry);
      return sqrt(dist);
}

Since some drums overlap others, the order in which we compare the distances is important.

if (get_distance(coordX, coordY, __pRide.x, __pRide.y) < __pRide.r) {
      play_audio(ad->player1);
} else {
      if (get_distance(coordX, coordY, __pCrash.x, __pCrash.y) < __pCrash.r) {
            play_audio(ad->player2);
      } else {
            if (get_distance(coordX, coordY, __pTom2.x, __pTom2.y) < __pTom2.r) {
                  play_audio(ad->player3);
            }
      }
}

 

The last thing to remember is to clean up before closing the app.

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

This has to be done for each and every player used.

File attachments: 
List
SDK Version Since: 
2.3.1