Esempio n. 1
0
void *ai_audio_context_save( uint8_t *status, uint16_t *size )
{
  if( !ai_async_audio_context_save() )
  {
    *status = false;
    return NULL;
  }

  do
  {
    AI_SYNC_TASK_CALL_BACK();
    ai_async_cmd_task();
  }while( !is_ai_async_cmd_finished() );

  *status = ai_async_cmd_out_status();
  *size   = ai_async_cmd_out_SizeArrayU8();
  return (void *)ai_async_cmd_out_PtrArrayU8();
}
Esempio n. 2
0
static void track_changed_task(struct state_machine_context *state_m)
{
  // By default, the command executed is asynchronous.
  state_m->async_cmd = true;
  Ai_player_flag_t player_flag_temp;

  switch (state_m->state)
  {
  case STATE_TRACK_CHANGED_ENTRY_POINT:
    memset(&state_m->info, 0, sizeof(struct file_info));
    ai_async_audio_nav_file_info_duration();
    state_m->state = STATE_TRACK_CHANGED_TOTAL_TIME;
    break;
  // Record total time info and call file name.
  case STATE_TRACK_CHANGED_TOTAL_TIME:
    state_m->info.total_time = ai_async_cmd_out_u32();
    ai_async_audio_nav_getname();
    state_m->state = STATE_TRACK_CHANGED_FILE_NAME;
    break;
  // Record file name information and call for artist metadata.
  case STATE_TRACK_CHANGED_FILE_NAME:
    unicode2ascii((char *) state_m->info.name,
                  (const char *) ai_async_cmd_out_PtrArrayU8(),
                  Min(ai_async_cmd_out_SizeArrayU8(), STR_MAX_LENGTH*2));
    ai_async_audio_nav_file_info_artist();
    state_m->state = STATE_TRACK_CHANGED_ARTIST;
    break;
  // Record artist metadata and call title metadata.
  case STATE_TRACK_CHANGED_ARTIST:
    unicode2ascii((char *) state_m->info.artist,
                  (const char *) ai_async_cmd_out_PtrArrayU8(),
                  Min(ai_async_cmd_out_SizeArrayU8(), STR_MAX_LENGTH*2));
    ai_async_audio_nav_file_info_title();
    state_m->state = STATE_TRACK_CHANGED_TITLE;
    break;
  // Record title metadata.
  case STATE_TRACK_CHANGED_TITLE:
    unicode2ascii((char *) state_m->info.title,
                  (const char *) ai_async_cmd_out_PtrArrayU8(),
                  Min(ai_async_cmd_out_SizeArrayU8(), STR_MAX_LENGTH*2));
#if defined(SUPPORT_EMBEDDED_COVER_ARTS) && SUPPORT_EMBEDDED_COVER_ARTS == true
    state_m->info.size.width = 100;
    state_m->info.size.height = 100;
    ai_async_audio_nav_file_info_image(&state_m->info.size);
    state_m->state = STATE_TRACK_CHANGED_IMAGE;
#else
    ai_async_audio_ctrl_status();
    state_m->state = STATE_TRACK_CHECK_RESUME;
#endif
    break;
  // Record image data.
  case STATE_TRACK_CHANGED_IMAGE:
    state_m->info.image_data = (void *) ai_async_cmd_out_u32();
    ai_async_audio_ctrl_status();
    state_m->state = STATE_TRACK_CHECK_RESUME;
    break;
  // Resume the track
  case STATE_TRACK_CHANGED_RESUME:
    state_m->async_cmd = false;
    state_m->state = state_m->recorded_state;
    break;
    // Check if the device is in pause before sending a ai_async_audio_ctrl_resume()
    // command.
  case STATE_TRACK_CHECK_RESUME:
    player_flag_temp.all = ai_async_cmd_out_u32();
    if (player_flag_temp.status == PLAYER_FLAG_PAUSE)
      ai_async_audio_ctrl_resume();
    state_m->state = STATE_TRACK_CHANGED_RESUME;
    break;
  default:
    return;
  }

  // Error management
  if (state_m->cmd_status == false)
    state_m->state = STATE_DEVICE_DISCONNECTED;
}
Esempio n. 3
0
static void navigation_task(struct state_machine_context *state_m)
{
  static size_t item_updated;
  static uint16_t temp_cursor_pos;
  size_t i;

  // By default, the command executed is asynchronous.
  state_m->async_cmd = true;
  state_m->view = GUI_UPDATE_VIEW_NAVIGATION;

  switch (state_m->state)
  {
  // This state id the entry point of the navigation view.
  // It must be call on every access to this view.
  case STATE_NAVIGATION_ENTRY_POINT:
    state_m->view_elt = GUI_UPDATE_ELT_NAVIGATION_CURSOR;
    state_m->async_cmd = false;
    state_m->cmd_status = true;
    // Update file_list relatives info.
    state_m->list.file_pos = 0;
    state_m->list.nb_files = 0xFFFF;
    state_m->list.nb_valid_entries = 0;
    temp_cursor_pos = 0;
    state_m->cursor_pointer = 0;
    // Invalidate all the items on the list
    for (i=0; i<MAX_BUFFER_FILE; i++)
      state_m->list.list[i].updated = false;
    state_m->state = STATE_NAVIGATION_UPDATE_LIST;
    break;
  // Update the file list from the current directory.
  case STATE_NAVIGATION_UPDATE_LIST:
    // Re-center the file list.
    if (temp_cursor_pos < state_m->list.file_pos &&
        state_m->list.nb_valid_entries)
    {
      // Scroll-down the list
      memmove((void *) &state_m->list.list[1],
              (const void *) &state_m->list.list[0],
              sizeof(state_m->list.list[0])*(MAX_BUFFER_FILE - 1));
      // Every element of the list have to be updated
      for (i=1; i<MAX_BUFFER_FILE; i++)
        state_m->list.list[i].updated = true;
      // Get information of the file.
      item_updated = 0;
      state_m->list.file_pos--;
      state_m->list.nb_valid_entries--;
      ai_async_nav_file_goto(state_m->list.file_pos + item_updated);
      state_m->view_elt |= GUI_UPDATE_ELT_IN_PROGRESS;
      state_m->state = STATE_NAVIGATION_UPDATE_LIST_GET_NAME;
      break;
    }
    if (temp_cursor_pos > state_m->list.file_pos &&
        state_m->list.nb_valid_entries)
    {
      // Scroll-up the list
      memmove((void *) &state_m->list.list[0],
              (const void *) &state_m->list.list[1],
              sizeof(state_m->list.list[0])*(MAX_BUFFER_FILE - 1));
      // Every element of the list have to be updated
      for (i=0; i<MAX_BUFFER_FILE-1; i++)
        state_m->list.list[i].updated = true;
      // Get information of the file.
      item_updated = MAX_BUFFER_FILE - 1;
      state_m->list.file_pos++;
      state_m->list.nb_valid_entries--;
      ai_async_nav_file_goto(state_m->list.file_pos + item_updated);
      state_m->view_elt |= GUI_UPDATE_ELT_IN_PROGRESS;
      state_m->state = STATE_NAVIGATION_UPDATE_LIST_GET_NAME;
      break;
    }
    // There is nothing to update
    state_m->async_cmd = false;
    state_m->view_elt |= GUI_UPDATE_ELT_IN_PROGRESS;
    state_m->state = STATE_NAVIGATION_WAIT_FOR_EVENT;
    break;
  // Read the file name of the file selected.
  case STATE_NAVIGATION_UPDATE_LIST_GET_NAME:
    // The case when there is no more files...
    if (state_m->cmd_status == false)
    {
      state_m->list.nb_files = state_m->list.file_pos + item_updated;
      // If no files/folders are found in the current directory...
      if (!state_m->list.nb_files)
        state_m->view_elt |= GUI_UPDATE_ELT_NAVIGATION_NO_FILES;
      state_m->cmd_status = true;
      state_m->async_cmd = false;
      navigation_update_view(state_m);
      state_m->state = STATE_NAVIGATION_WAIT_FOR_EVENT;
      break;
    }
    ai_async_nav_file_name();
    state_m->view_elt |= GUI_UPDATE_ELT_IN_PROGRESS;
    state_m->state = STATE_NAVIGATION_UPDATE_LIST_STORE_NAME;
    break;
  // Store the file name of the selected file.
  case STATE_NAVIGATION_UPDATE_LIST_STORE_NAME:
    unicode2ascii((char *) state_m->list.list[item_updated].file_name,
                  (const char *) ai_async_cmd_out_PtrArrayU8(),
                  Min(ai_async_cmd_out_SizeArrayU8(), STR_MAX_LENGTH*2));
    ai_async_nav_file_isdir();
    state_m->view_elt |= GUI_UPDATE_ELT_IN_PROGRESS;
    state_m->state = STATE_NAVIGATION_UPDATE_ISDIR;
    break;
  // Check if the selected file is a directory or not.
  case STATE_NAVIGATION_UPDATE_ISDIR:
    state_m->list.list[item_updated].type = (ai_async_cmd_out_u32())?FILE_TYPE_DIRECTORY:FILE_TYPE_FILE;
    state_m->list.list[item_updated].updated = true;
    state_m->list.nb_valid_entries++;
    navigation_update_view(state_m);
    state_m->async_cmd = false;
    state_m->view_elt |= GUI_UPDATE_ELT_IN_PROGRESS;
    state_m->state = STATE_NAVIGATION_UPDATE_LIST;
    break;
  // This state is the "idle" state of this view.
  case STATE_NAVIGATION_WAIT_FOR_EVENT:
    // Catch new track event
    state_m->cmd_status = true;
    if (state_m->player_status.flags.new_file_played)
    {
      state_m->async_cmd = false;
      state_m->player_status.flags.new_file_played = 0;
      state_m->recorded_state = STATE_NAVIGATION_WAIT_FOR_EVENT;
      state_m->state = STATE_TRACK_CHANGED_ENTRY_POINT;
      break;
    }
    // Switch to playback view
    else if (controller_switch_to_playback_view(GUI_UPDATE_VIEW_NAVIGATION))
    {
      controller_clear();
      state_m->async_cmd = false;
      state_m->state = STATE_PLAYBACK_ENTRY_POINT;
      break;
    }
    // Switch to configuration view
    else if (controller_switch_to_config_view(GUI_UPDATE_VIEW_NAVIGATION))
    {
      controller_clear();
      state_m->async_cmd = false;
      state_m->state = STATE_CONFIG_ENTRY_POINT;
      break;
    }
    // Go up in the file list.
    else if (controller_navigation_cursor_previous() &&
             temp_cursor_pos)
    {
      state_m->async_cmd = false;
      temp_cursor_pos--;
      state_m->state = STATE_NAVIGATION_UPDATE_LIST;
      break;
    }
    // Go down in the file list.
    else if (controller_navigation_cursor_next() &&
             (temp_cursor_pos + 1 < state_m->list.file_pos + state_m->list.nb_valid_entries))
    {
      state_m->async_cmd = false;
      temp_cursor_pos++;
      state_m->state = STATE_NAVIGATION_UPDATE_LIST;
      break;
    }
    // Enter directory of play the file.
    else if (controller_navigation_change_directory())
    {
      if (navigation_get_current_file_type(state_m) == FILE_TYPE_FILE)
      {
        ai_async_nav_file_goto(temp_cursor_pos);
        state_m->state = STATE_NAVIGATION_PLAY_SELECTED_FILE;
        break;
      }
      else
      {
        ai_async_nav_file_goto(temp_cursor_pos);
        state_m->state = STATE_NAVIGATION_CD;
        break;
      }
    }
    // Go to parent directory.
    else if (controller_navigation_go_to_parent_directory())
    {
      ai_async_nav_file_goto(temp_cursor_pos);
      state_m->state = STATE_NAVIGATION_GOTOPARENT;
      break;
    }
    // Play the file or the directory.
    else if (controller_navigation_play())
    {
      ai_async_nav_file_goto(temp_cursor_pos);
      state_m->state = STATE_NAVIGATION_PLAY_SELECTED_FILE;
      break;
    }
    // Fill the file list with valid data.
    else if (state_m->list.nb_valid_entries < MAX_BUFFER_FILE &&
             state_m->list.file_pos + state_m->list.nb_valid_entries < state_m->list.nb_files)
    {
      item_updated = state_m->list.nb_valid_entries;
      ai_async_nav_file_goto(state_m->list.file_pos + state_m->list.nb_valid_entries);
      state_m->view_elt |= GUI_UPDATE_ELT_IN_PROGRESS;
      state_m->state = STATE_NAVIGATION_UPDATE_LIST_GET_NAME;
      break;
    }
    state_m->async_cmd = false;
    state_m->state = STATE_CHECK_DEVICE_ENTRY_POINT;
    state_m->recorded_state = STATE_NAVIGATION_WAIT_FOR_EVENT;
    break;
  // Enter directory.
  case STATE_NAVIGATION_CD:
    ai_async_nav_dir_cd();
    state_m->state = STATE_NAVIGATION_ENTRY_POINT;
    break;
  // Go to parent directory.
  case STATE_NAVIGATION_GOTOPARENT:
    state_m->cmd_status = true;
    ai_async_nav_dir_gotoparent();
    state_m->state = STATE_NAVIGATION_GOTOPARENT_ERROR_HANDLING;
    break;
  // This state handle a gotoparent error.
  case STATE_NAVIGATION_GOTOPARENT_ERROR_HANDLING:
    state_m->async_cmd = false;
    if (state_m->cmd_status == false)
      state_m->state = STATE_NAVIGATION_WAIT_FOR_EVENT;
    else
      state_m->state = STATE_NAVIGATION_ENTRY_POINT;
    state_m->cmd_status = true;
    break;
  // This states play the file selected by the cursor.
  case STATE_NAVIGATION_PLAY_SELECTED_FILE:
    if (state_m->cmd_status)
      ai_async_audio_nav_playfile();
    else
    {
      state_m->cmd_status = true;
      state_m->async_cmd = false;
      state_m->state = STATE_NAVIGATION_ENTRY_POINT;
      break;
    }
    state_m->state = STATE_NAVIGATION_WAIT_FOR_SELECTION;
    break;
  // This states makes sure the file has been selected
  case STATE_NAVIGATION_WAIT_FOR_SELECTION:
    // If we were not able to play the selected song, then play any song
    if (!state_m->cmd_status)
    {
      state_m->cmd_status = true;
      state_m->state = STATE_COMMAND_PLAY_ANY_SONG;
    }
    else
    state_m->state = STATE_CHECK_DEVICE_ENTRY_POINT;
    state_m->recorded_state = STATE_NAVIGATION_UPDATE_METADATA_AND_PLAY;
    state_m->async_cmd = false;
    break;
  // This state update the status of the audio player.
  case STATE_NAVIGATION_UPDATE_METADATA_AND_PLAY:
    state_m->async_cmd = false;
    state_m->player_status.flags.new_file_played = 0;
    state_m->recorded_state = STATE_PLAYBACK_ENTRY_POINT;
    state_m->state = STATE_TRACK_CHANGED_ENTRY_POINT;
    break;

  default:
    return;
  }

  // Error management.
  if (state_m->cmd_status == false)
    state_m->state = STATE_NAVIGATION_WAIT_FOR_EVENT;
}