From: Radek Kintop Date: Tue, 1 Dec 2015 10:03:40 +0000 (+0100) Subject: Mobile radio sample documentation X-Git-Tag: tizen_3.0/TD_SYNC/20161201~294^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b3dc2f9277c5092f0027bbd1f0c7f7beef7eaf1b;p=sdk%2Fonline-doc.git Mobile radio sample documentation Change-Id: I72ddb358b5c79763e482ebd0462f124d378161c1 Signed-off-by: Radek Kintop --- diff --git a/org.tizen.sampledescriptions/html/images/radio_screen_0.png b/org.tizen.sampledescriptions/html/images/radio_screen_0.png new file mode 100644 index 0000000..46f2cf7 Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/radio_screen_0.png differ diff --git a/org.tizen.sampledescriptions/html/images/radio_screen_1.png b/org.tizen.sampledescriptions/html/images/radio_screen_1.png new file mode 100644 index 0000000..22053bd Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/radio_screen_1.png differ diff --git a/org.tizen.sampledescriptions/html/mobile_n/radio_sd_mn.htm b/org.tizen.sampledescriptions/html/mobile_n/radio_sd_mn.htm new file mode 100644 index 0000000..eb77652 --- /dev/null +++ b/org.tizen.sampledescriptions/html/mobile_n/radio_sd_mn.htm @@ -0,0 +1,448 @@ + + + + + + + + + + + + + Radio Sample Overview + + + + +
+
+ +
+
+

Mobile native

+
+

Radio Sample Overview

+ +

The Radio sample application demonstrates how you can create an application utilizing Radio API. The application interface consists of a main window (old style radio view) and a simple menu +containing a list of known (scanned) frequencies. After a successful scan, just press the menu button and the list will appear.

+

This application has been designed as multithreaded to avoid main rendering loop lockups in case of multiple frequency set commands. +It takes some time for the radio hardware to set itself up.

+ +

Figure: Application views

+

+ Radio view + List of known frequencies +

+ +

You can change the frequency manually, using the knob or let the radio seek the station for you. The signal strength indicator can help you tune the radio. +To obtain the list of strongest stations frequencies, press the scan buton. Scanning turns the radio off, so afterwards you have to switch it back on manually.

+ +

Prerequisites

+

This application requires the device to support the following feature:

+
    +
  • http://tizen.org/feature/fmradio .
  • +
+ +

Implementation

+ +

Main controller

+ +

There are two important functions in this module: +__radio_cb() and +__ui_cb(). The first one reacts to radio module changes and sets up the +application view accordingly. The latter one does the opposite - it invokes radio module functions depending on user interface selections.

+ +
+static void __radio_cb(radio_event event)
+{
+  //Variables definition ...
+
+  switch (event) {
+  case RADIO_EVENT_SCAN_END:
+    if(radio_controller_get_known_stations(&stations_arr, &stations_arr_len) &&
+      stations_arr_len > 0) {
+      for (int i = 0; i < stations_arr_len; i++)
+        view_add_station(stations_arr[i]);
+    }
+    view_lock_ui(false);
+    view_show_on_off(radio_controller_is_on());
+    view_show_scanning(false);
+    if (radio_controller_is_muted(&muted))
+      view_show_muted(muted);
+    view_show_seeking(false, false);
+    view_show_seeking(false, true);
+    break;
+  case RADIO_EVENT_SCAN_UPDATE:
+    __setup_ui_freq();
+    break;
+  case RADIO_EVENT_SEEK_END:
+    view_lock_ui(false);
+    view_show_on_off(radio_controller_is_on());
+    view_show_scanning(false);
+    if (radio_controller_is_muted(&muted))
+      view_show_muted(muted);
+    view_show_seeking(false, false);
+    view_show_seeking(false, true);
+    __setup_ui_freq();
+    break;
+  case RADIO_EVENT_RSSI_UPDATE:
+    __setup_ui_rssi();
+    break;
+  case RADIO_EVENT_INTERRUPTION:
+    radio_controller_set_on(false);
+    __setup_ui();
+    break;
+  case RADIO_EVENT_FREQ_SET:
+    break;
+  default:
+    break;
+  }
+}
+
+ +
+static void __ui_cb(ui_event event, ui_element element, const void *data)
+{
+  //Variables definition ...
+  bool activate_button = (event == UI_EVENT_BUTTON_ACTIVATE);
+
+  if (event == UI_EVENT_FREQ_CHANGE && data) {
+    frequency = (float)(*(double *)data);
+
+    if (!radio_controller_set_frequency(frequency * 1000.0))
+      //Error handling ...
+
+    return;
+  }
+
+  if (event == UI_EVENT_FREQ_CHANGE_END) {
+    __setup_ui_freq();
+    return;
+  }
+
+  if (event == UI_EVENT_STATION_SELECTION && data) {
+    selected_station = *(int *)data;
+    if(radio_controller_get_known_stations(&stations_arr, &stations_arr_len) &&
+      selected_station >= 0 && selected_station < stations_arr_len
+      ) {
+      if (radio_controller_set_frequency(stations_arr[selected_station])) {
+        view_show_frequency((float)stations_arr[selected_station] / 1000.0);
+      }
+    }
+    return;
+  }
+
+  if (event == UI_EVENT_BUTTON_ACTIVATE || event == UI_EVENT_BUTTON_DEACTIVATE)
+    switch (element) {
+    case UI_ELEMENT_ON_OFF_BUTTON:
+      if ((result_ok = radio_controller_set_on(activate_button)))
+        view_show_on_off(activate_button);
+      break;
+    case UI_ELEMENT_MUTE_BUTTON:
+      if ((result_ok = radio_controller_mute(activate_button)))
+        view_show_muted(activate_button);
+      break;
+    case UI_ELEMENT_SCAN_BUTTON:
+      if ((result_ok = radio_controller_start_scan(activate_button))) {
+        if (activate_button) {
+          view_clear_stations();
+          view_lock_ui(true);
+        }
+        view_show_scanning(activate_button);
+      }
+      break;
+    case UI_ELEMENT_SEEK_MINUS_BUTTON:
+    case UI_ELEMENT_SEEK_PLUS_BUTTON:
+      if (!activate_button) {
+        result_ok = true;
+        break;
+      }
+      if ((result_ok = radio_controller_start_seek(element == UI_ELEMENT_SEEK_PLUS_BUTTON))) {
+        view_show_seeking(true, element == UI_ELEMENT_SEEK_PLUS_BUTTON);
+        view_lock_ui(true);
+      }
+      break;
+    default:
+      break;
+    }
+}
+
+ +

Radio controller

+ +

This is module is the essence of the application.

+

The radio_controller_init() +function is used to obtain handles for the radio resource and the timer as well as to set callbacks for the following events:

+
    +
  • scan command completion event,
  • +
  • radio operation interruption event,
  • +
  • timer timeout event (used to periodically poll for the RSSI).
  • +
+ +
+bool radio_controller_init(radio_cb cb)
+{
+  //Common code ...
+
+  ret = radio_create(&radio_data.handle);
+
+  //Error handling ...
+
+  ret = radio_set_scan_completed_cb(radio_data.handle, __radio_scan_completed_cb, NULL);
+  //Error handling ...
+
+  ret = radio_set_interrupted_cb(radio_data.handle, __radio_interrupted_cb, NULL);
+  //Error handling ...
+
+  radio_data.tim = ecore_timer_add(RSSI_POLL_INTERVAL, __rssi_tim_cb, NULL);
+
+  //Error handling and common code...
+}
+
+ +

The radio_controller_set_on() +function uses API calls to +radio_start() and +radio_stop() .

+ +
+bool radio_controller_set_on(bool on_off)
+{
+  int res = RADIO_ERROR_NONE;
+
+  if (on_off) {
+    res = radio_start(radio_data.handle);
+    radio_data.state = RADIO_STATE_PLAYING;
+
+  } else {
+    res = radio_stop(radio_data.handle);
+    radio_data.state = RADIO_STATE_READY;
+  }
+
+  return true;
+}
+
+ +

The radio_controller_set_frequency() +function uses ecore thread to set up the selected frequency. Such approach is used because this operation takes a long time to complete. +Calling radio_set_frequency() +function directly would block the main event loop.

+ +
+bool radio_controller_set_frequency(int freq)
+{
+  if (!radio_data.thread_h && (__radio_is_in_state(RADIO_STATE_PLAYING) || __radio_is_in_state(RADIO_STATE_READY))) {
+    radio_data.thread_h = ecore_thread_run(__thread_function, __thread_end_cb, NULL, (void *)freq);
+
+     return (radio_data.thread_h != NULL);
+  }
+
+  return false;
+}
+
+ +
+static void __thread_function(void *frequency, Ecore_Thread *thread)
+{
+  radio_set_frequency(radio_data.handle, (int)frequency);
+}
+
+ +
+static void __thread_end_cb(void *data, Ecore_Thread *thread)
+{
+  if (radio_data.cb)
+    radio_data.cb(RADIO_EVENT_FREQ_SET);
+
+  radio_data.thread_h = NULL;
+}
+
+ +

The radio_controller_start_scan() +function issues asynchronous scan command. This automatically shuts the radio off.

+ +
+bool radio_controller_start_scan(bool start_stop)
+{
+  int ret = RADIO_ERROR_NONE;
+
+  if (radio_data.thread_h != NULL)
+    return false;
+
+  if (start_stop) {
+
+    if (!radio_controller_set_on(false))
+      return false;
+
+    ret = radio_scan_start(radio_data.handle, __radio_scan_updated_cb, NULL);
+
+    if (RADIO_ERROR_NONE != ret)
+      return false;
+
+    radio_data.known_freq_ix = 0;
+
+  } else {
+
+    ret = radio_scan_stop(radio_data.handle, __radio_scan_stopped_cb, NULL);
+
+    if (RADIO_ERROR_NONE != ret)
+      return false;
+  }
+
+  return true;
+}
+
+ +

Each time a radio station frequency is found, +the __radio_scan_updated_cb() +callback is invoked. The callback is used to update the known frequencies list.

+ +
+static void __radio_scan_updated_cb(int frequency, void *user_data)
+{
+  if (radio_data.known_freq_ix < KNOWN_STATIONS_MAX) {
+
+    radio_data.known_freq[radio_data.known_freq_ix++] = frequency;
+
+    if (radio_data.cb)
+      radio_data.cb(RADIO_EVENT_SCAN_UPDATE);
+  }
+}
+
+ +

Once the scan is completed, +__radio_scan_completed_cb() +callback function is invoked.

+ +
+static void __radio_scan_completed_cb(void *user_data)
+{
+  if (radio_data.cb)
+    radio_data.cb(RADIO_EVENT_SCAN_END);
+}
+
+ +
+bool radio_controller_mute(bool mute)
+{
+  return (RADIO_ERROR_NONE == radio_set_mute(radio_data.handle, mute));
+}
+
+ +

The radio_controller_start_seek() +function runs an asynchronous command which finds the nearest channel (in sense of frequency). +The __radio_seek_completed_cb +callback function is invoked upon this operation's completion.

+ +
+bool radio_controller_start_seek(bool up_down)
+{
+  if (__radio_is_in_state(RADIO_STATE_SCANNING) || !radio_controller_set_on(true))
+    return false;
+
+  if (up_down) {
+    return (RADIO_ERROR_NONE == radio_seek_up(radio_data.handle, __radio_seek_completed_cb, NULL));
+  } else {
+    return (RADIO_ERROR_NONE == radio_seek_down(radio_data.handle, __radio_seek_completed_cb, NULL));
+  }
+}
+
+ +
+static void __radio_seek_completed_cb(int frequency, void *user_data)
+{
+  if (radio_data.cb)
+    radio_data.cb(RADIO_EVENT_SEEK_END);
+}
+
+ +

The __rssi_tim_cb() +function is the poll timer timeout event callback. +Whenever it is called, it notifies the main controller +module to update itself on a RSSI status. +

+ +
+static Eina_Bool __rssi_tim_cb(void *data)
+{
+  if (radio_data.cb)
+    radio_data.cb(RADIO_EVENT_RSSI_UPDATE);
+
+  return EINA_TRUE;
+}
+
+ +

The following functions represent getters of the radio module. +You can get the current frequency the radio is set to, the radio frequency range and the signal strength as well as check whether the radio is muted/on.

+ +
+bool radio_controller_is_on(void)
+{
+  return __radio_is_in_state(RADIO_STATE_PLAYING);
+}
+
+ +
+bool radio_controller_is_muted(bool *muted)
+{
+  return (RADIO_ERROR_NONE == radio_is_muted(radio_data.handle, muted));
+}
+
+ +
+bool radio_controller_get_rssi(float *strength)
+{
+  //Error handling ...
+  if (RADIO_ERROR_NONE != radio_get_signal_strength(radio_data.handle, &dBm))
+    return false;
+
+  *strength = (float)(dBm + 128.0) / (2.0 * 128.0);
+
+  if (*strength <= 0.0)
+    *strength = 0.0;
+
+  if (*strength >= 1.0)
+    *strength = 1.0;
+
+  return true;
+}
+
+ +
+bool radio_controller_get_freq(int *freq)
+{
+  return (RADIO_ERROR_NONE == radio_get_frequency(radio_data.handle, freq));
+}
+
+ +
+bool radio_controller_get_freq_range(int *freq_min, int *freq_max)
+{
+  return (RADIO_ERROR_NONE == radio_get_frequency_range(radio_data.handle, freq_min, freq_max));
+}
+
+ + + +
+ +Go to top + + + + + + + diff --git a/org.tizen.sampledescriptions/html/mobile_n/sd_mn.htm b/org.tizen.sampledescriptions/html/mobile_n/sd_mn.htm index 45ddfc7..c69b28e 100644 --- a/org.tizen.sampledescriptions/html/mobile_n/sd_mn.htm +++ b/org.tizen.sampledescriptions/html/mobile_n/sd_mn.htm @@ -235,6 +235,10 @@ Demonstrates how you can implement a complex view using recursive composition of the standard EFL components. + Radio + Demonstrates how you can create an application utilizing Radio API. + + Resource Management Demonstrates how you can use the Resource Manager API together with the SDK's Resource Manager to benefit from task automation.