pinebuds/apps/audioplayers/rbplay/rb_ctl.cpp

834 lines
22 KiB
C++

/***************************************************************************
*
* Copyright 2015-2019 BES.
* All rights reserved. All unpublished rights reserved.
*
* No part of this work may be used or reproduced in any form or by any
* means, or stored in a database or retrieval system, without prior written
* permission of BES.
*
* Use of this work is governed by a license granted by BES.
* This work contains confidential and proprietary information of
* BES. which is protected by copyright, trade secret,
* trademark and other intellectual property rights.
*
****************************************************************************/
/* rbplay source */
/* playback control & rockbox codec porting & codec thread */
#ifdef MBED
#include "mbed.h"
#include "rtos.h"
#endif
#include "SDFileSystem.h"
#include "app_audio.h"
#include "audioflinger.h"
#include "cqueue.h"
#include "hal_timer.h"
#include "hal_trace.h"
#include "hal_uart.h"
#include <ctype.h>
#include <fcntl.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "audiohw.h"
#include "channel_mode.h"
#include "codec_platform.h"
#include "codeclib.h"
#include "codecs.h"
#include "compressor.h"
#include "dsp_core.h"
#include "eq.h"
#include "metadata.h"
#include "metadata_parsers.h"
#include "pga.h"
#include "app_key.h"
#include "app_overlay.h"
#include "app_thread.h"
#include "app_utils.h"
#include "hal_overlay.h"
#include "rbpcmbuf.h"
#include "rbplay.h"
#include "rb_ctl.h"
#include "rbplaysd.h"
/* Internals */
void rb_ctl_wait_lock_thread(bool lock);
void app_rbcodec_ctl_set_play_status(bool st);
extern bool app_rbcodec_check_hfp_active(void);
#include "SDFileSystem.h"
extern "C" void hal_sysfreq_print(void);
#define _LOG_TAG "[rb_ctl] "
#undef __attribute__(a)
#define RBPLAY_DEBUG 1
#if RBPLAY_DEBUG
#define _LOG_DBG(str, ...) TRACE(0, _LOG_TAG "" str, ##__VA_ARGS__)
#define _LOG_ERR(str, ...) \
TRACE(0, \
_LOG_TAG "err:" \
"" str, \
##__VA_ARGS__)
#else
#define _LOG_DBG(str, ...)
#define _LOG_ERR(str, ...) \
TRACE(0, \
_LOG_TAG "err:" \
"" str, \
##__VA_ARGS__)
#endif
#include "rb_ctl.h"
void rb_thread_send_resume(void);
typedef struct {
uint32_t evt;
uint32_t arg;
} RBCTL_MSG_BLOCK;
static osThreadId rb_ctl_tid;
static void rb_ctl_thread(void const *argument);
static int rb_ctl_default_priority;
osThreadDef(rb_ctl_thread, osPriorityHigh, 1, 1024 * 4, "rb_ctl");
#define RBCTL_MAILBOX_MAX (20)
osMailQDef(rb_ctl_mailbox, RBCTL_MAILBOX_MAX, RBCTL_MSG_BLOCK);
static osMailQId rb_ctl_mailbox = NULL;
int rb_ctl_mailbox_put(RBCTL_MSG_BLOCK *msg_src);
// playlist
extern playlist_struct sd_playlist;
rb_ctl_struct rb_ctl_context;
extern void rb_thread_set_decode_vars(int fd, int type, void *id3);
extern void rb_play_codec_run(void);
extern void rb_codec_set_halt(int halt);
extern void rb_player_sync_set_wait_thread(osThreadId tid);
extern void rb_player_sync_wait_close(void);
extern bool rb_pcmbuf_suspend_play_loop(void);
void app_rbplay_load_playlist(playlist_struct *list);
int rb_thread_post_msg(RB_MODULE_EVT evt, uint32_t arg);
static rb_ctl_status rb_ctl_get_status(void) { return rb_ctl_context.status; }
bool rb_ctl_parse_file(const char *file_path) {
/* open file */
_LOG_DBG(1, "open file %s\n", file_path);
rb_ctl_context.file_handle = open((const char *)file_path, O_RDWR);
if (rb_ctl_context.file_handle <= 0) {
_LOG_DBG(1, "open file %s failed\n", file_path);
return false;
}
if (!get_metadata(&rb_ctl_context.song_id3, rb_ctl_context.file_handle,
rb_ctl_context.rb_fname)) {
_LOG_DBG(0, "get_metadata failed\n");
close(rb_ctl_context.file_handle);
return false;
}
_LOG_DBG(4, "%s bitr:%d,saps %d, freq:%d\n", __func__,
rb_ctl_context.song_id3.bitrate, rb_ctl_context.song_id3.samples,
rb_ctl_context.song_id3.frequency);
rb_thread_set_decode_vars(rb_ctl_context.file_handle,
rb_ctl_context.song_id3.codectype,
&rb_ctl_context.song_id3);
return true;
}
void rb_ctl_vol_operation(bool inc) {
uint32_t ret;
struct AF_STREAM_CONFIG_T *stream_cfg = NULL;
_LOG_DBG(2, "%s inc:%d , ", __func__, inc);
if (inc) {
if (rb_ctl_context.rb_player_vol < 16) {
rb_ctl_context.rb_player_vol++;
}
} else {
if (rb_ctl_context.rb_player_vol > 1) {
rb_ctl_context.rb_player_vol--;
}
}
if (rb_ctl_context.status != RB_CTL_PLAYING)
return;
ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg,
true);
if (ret == 0) {
stream_cfg->vol = rb_ctl_context.rb_player_vol;
af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, stream_cfg);
}
}
bool rb_ctl_is_playing(void) {
return (rb_ctl_context.status == RB_CTL_PLAYING);
}
void rb_ctl_set_vol(uint32_t vol) {
uint32_t ret;
struct AF_STREAM_CONFIG_T *stream_cfg = NULL;
_LOG_DBG(2, "%s set vol as :%d , ", __func__, vol);
if (rb_ctl_context.status != RB_CTL_PLAYING)
return;
vol = (vol > 16) ? 16 : vol;
rb_ctl_context.rb_player_vol = vol;
ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg,
true);
if (ret == 0) {
stream_cfg->vol = rb_ctl_context.rb_player_vol;
af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, stream_cfg);
}
}
void rb_ctl_stop_play(void) {
_LOG_DBG(1, "%s \n", __func__);
rb_codec_set_halt(1);
// close file
_LOG_DBG(0, " af stream stop \n");
af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK);
_LOG_DBG(0, " af stream close \n");
af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK);
_LOG_DBG(0, " close file \n");
if (rb_ctl_context.file_handle != -1)
close(rb_ctl_context.file_handle);
rb_ctl_context.file_handle = -1;
// release frequency
_LOG_DBG(0, " release freq \n");
return;
}
void rb_ctl_sync_stop_play(void) {
rb_player_sync_set_wait_thread(osThreadGetId());
rb_ctl_stop_play();
rb_player_sync_wait_close();
// close file
_LOG_DBG(0, " close file \n");
if (rb_ctl_context.file_handle != -1)
close(rb_ctl_context.file_handle);
rb_ctl_context.file_handle = -1;
}
void rb_ctl_pause_playing(void) {
af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK);
_LOG_DBG(0, " af stream close \n");
af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK);
// wait decoder suspend
// osDelay(200);
// while(!rb_pcmbuf_suspend_play_loop()) {
// osThreadYield();
// osDelay(1);
// }
_LOG_DBG(1, "%s sucessed ", __func__);
}
void rb_ctl_resume_playing(void) {
#ifndef __TWS__
rb_pcmbuf_init();
#endif
}
void rb_ctl_set_priority(int priority) {
osThreadSetPriority(rb_ctl_tid, (osPriority)priority);
}
int rb_ctl_get_priority(void) { return (int)osThreadGetPriority(rb_ctl_tid); }
int rb_ctl_get_default_priority(void) { return rb_ctl_default_priority; }
void rb_ctl_reset_priority(void) {
osThreadSetPriority(rb_ctl_tid, (osPriority)rb_ctl_default_priority);
}
#ifdef __IAG_BLE_INCLUDE__
extern "C" void app_ble_inform_music_switch(uint16_t index);
#endif
static int rb_ctl_handle_event(RBCTL_MSG_BLOCK *msg_body) {
RB_MODULE_EVT evt = (RB_MODULE_EVT)msg_body->evt;
uint32_t arg = msg_body->arg;
// hal_sysfreq_print();
switch (evt) {
case RB_MODULE_EVT_PLAY:
if (rb_ctl_context.status != RB_CTL_IDLE) {
if (rb_ctl_context.status == RB_CTL_SUSPEND)
rb_thread_send_resume();
else
_LOG_DBG(2, "%s st %d not in idle \n", __func__,
rb_ctl_context.status);
break;
}
_LOG_DBG(3, " %s start %d/%d ", __func__, rb_ctl_context.curr_song_idx,
sd_playlist.total_songs);
if (sd_playlist.total_songs > 0) {
playlist_item *it;
it = app_rbplay_get_playitem(rb_ctl_context.curr_song_idx);
if (it == NULL) {
_LOG_DBG(2, " %s get item fail idx %d", __func__,
rb_ctl_context.curr_song_idx);
}
_LOG_DBG(2, "%s start songidx %d \n", __func__,
rb_ctl_context.curr_song_idx);
memcpy(rb_ctl_context.rb_audio_file, it->file_path,
sizeof(uint16_t) * FILE_PATH_LEN - 4);
memcpy(rb_ctl_context.rb_fname, it->file_name,
sizeof(rb_ctl_context.rb_fname));
if (rb_ctl_parse_file((const char *)rb_ctl_context.rb_audio_file)) {
_LOG_DBG(2, "%s start init, the tid 0x%x\n", __func__,
osThreadGetId());
rb_play_codec_init();
_LOG_DBG(1, "%s start run\n", __func__);
rb_play_codec_run();
rb_ctl_context.status = RB_CTL_PLAYING;
app_rbcodec_ctl_set_play_status(true);
break;
} else {
_LOG_DBG(2, "%s evt %d parse fail,find next\n", __func__,
msg_body->evt);
rb_thread_post_msg(RB_MODULE_EVT_PLAY_NEXT, true);
}
} else {
_LOG_DBG(2, "%s evt %d no songs\n", __func__, msg_body->evt);
}
break;
case RB_MODULE_EVT_STOP:
if (rb_ctl_context.status == RB_CTL_IDLE) {
_LOG_DBG(2, "%s st %d in idle \n", __func__, rb_ctl_context.status);
break;
}
if (rb_ctl_context.status == RB_CTL_SUSPEND) {
// osDelay(100);
rb_ctl_resume_playing();
rb_ctl_context.status = RB_CTL_PLAYING;
}
rb_ctl_sync_stop_play();
rb_ctl_context.status = RB_CTL_IDLE;
app_rbcodec_ctl_set_play_status(false);
break;
case RB_MODULE_EVT_SUSPEND:
if (rb_ctl_context.status != RB_CTL_PLAYING) {
_LOG_DBG(2, "%s st %d not running \n", __func__, rb_ctl_context.status);
break;
}
rb_ctl_pause_playing();
rb_ctl_context.status = RB_CTL_SUSPEND;
break;
case RB_MODULE_EVT_RESUME:
if (rb_ctl_context.status != RB_CTL_SUSPEND) {
_LOG_DBG(2, "%s st %d not suspend \n", __func__, rb_ctl_context.status);
break;
}
rb_ctl_resume_playing();
rb_ctl_context.status = RB_CTL_PLAYING;
break;
case RB_MODULE_EVT_PLAY_NEXT:
if (rb_ctl_context.status == RB_CTL_PLAYING) {
rb_thread_post_msg(RB_MODULE_EVT_STOP, 0);
} else if (rb_ctl_context.status == RB_CTL_SUSPEND) {
rb_thread_post_msg(RB_MODULE_EVT_STOP, 0);
} else {
}
if (arg == 0) {
rb_ctl_context.curr_song_idx--;
if (rb_ctl_context.curr_song_idx == 0xffff)
rb_ctl_context.curr_song_idx = sd_playlist.total_songs - 1;
} else {
rb_ctl_context.curr_song_idx++;
if (rb_ctl_context.curr_song_idx >= sd_playlist.total_songs)
rb_ctl_context.curr_song_idx = 0;
}
#ifdef __IAG_BLE_INCLUDE__
app_ble_inform_music_switch(rb_ctl_context.curr_song_idx);
#endif
rb_thread_post_msg(RB_MODULE_EVT_PLAY, 0);
break;
case RB_MODULE_EVT_CHANGE_VOL:
rb_ctl_vol_operation(arg);
break;
case RB_MODULE_EVT_SET_VOL:
rb_ctl_set_vol(arg);
break;
case RB_MODULE_EVT_CHANGE_IDLE:
rb_ctl_stop_play();
rb_ctl_context.status = RB_CTL_IDLE;
break;
case RB_MODULE_EVT_PLAY_IDX:
if (arg > sd_playlist.total_songs - 1) {
break;
}
if (rb_ctl_context.status == RB_CTL_PLAYING) {
rb_thread_post_msg(RB_MODULE_EVT_STOP, 0);
} else if (rb_ctl_context.status == RB_CTL_SUSPEND) {
rb_thread_post_msg(RB_MODULE_EVT_STOP, 0);
} else {
}
rb_ctl_context.curr_song_idx = (uint16_t)arg;
rb_thread_post_msg(RB_MODULE_EVT_PLAY, 0);
break;
// for voice cocah
#if 0
case SBCREADER_ACTION_INIT:
//prepare fs
voiceCocah_prepare_fs();
//init the data buff
voiceCocah_read_sbc_data();
break;
case SBCREADER_ACTION_RUN:
//fill sbc queue
voiceCocah_read_sbc_data();
break;
case SBCREADER_ACTION_STOP:
//release the res
voiceCocah_stop_clean();
rb_ctl_reset_priority();
break;
#endif
#ifdef __TWS__
case RB_MODULE_EVT_RESTORE_DUAL_PLAY:
extern void rb_restore_dual_play(uint8_t stream_type);
rb_restore_dual_play(arg);
break;
#endif
case RB_MODULE_EVT_DEL_FILE:
static rb_ctl_status prev_status = rb_ctl_context.status;
if (rb_ctl_context.status == RB_CTL_PLAYING) {
rb_thread_post_msg(RB_MODULE_EVT_STOP, 0);
rb_thread_post_msg(RB_MODULE_EVT_DEL_FILE, arg);
} else if (rb_ctl_context.status == RB_CTL_SUSPEND) {
rb_thread_post_msg(RB_MODULE_EVT_STOP, 0);
rb_thread_post_msg(RB_MODULE_EVT_DEL_FILE, arg);
} else {
app_ctl_remove_file(arg);
if (prev_status == RB_CTL_PLAYING) {
rb_thread_post_msg(RB_MODULE_EVT_PLAY, 0);
}
}
break;
#if defined(TWS_LINEIN_PLAYER)
case RB_MODULE_EVT_LINEIN_START:
extern int app_linein_codec_start(void);
app_linein_codec_start();
break;
case RB_MODULE_EVT_RECONFIG_STREAM:
extern void rb_tws_reconfig_stream(uint32_t arg);
rb_tws_reconfig_stream(arg);
break;
case RB_MODULE_EVT_SET_TWS_MODE:
break;
#endif
#ifdef SBC_RECORD_TEST
case SBC_RECORD_ACTION_START: {
rb_ctl_context.sbc_record_on = true;
app_rbplay_set_store_flag(true);
app_rbplay_open_sbc_file();
} break;
case SBC_RECORD_ACTION_DATA_IND: {
if (rb_ctl_context.sbc_record_on) {
app_rbplay_process_sbc_data();
}
} break;
case SBC_RECORD_ACTION_STOP: {
rb_ctl_context.sbc_record_on = false;
app_rbplay_set_store_flag(false);
app_rbplay_close_sbc_file();
} break;
#endif
default:
break;
}
if (SBC_RECORD_ACTION_DATA_IND != msg_body->evt)
_LOG_DBG(3, "%s rbcodec evt %d ,st %d ended\n", __func__, msg_body->evt,
rb_ctl_context.status);
return 0;
}
int rb_thread_post_msg(RB_MODULE_EVT evt, uint32_t arg) {
int ret;
RBCTL_MSG_BLOCK msg;
if (!rb_ctl_tid)
return 0;
/* APIs */
msg.evt = (uint32_t)evt;
msg.arg = (uint32_t)arg;
ret = rb_ctl_mailbox_put(&msg);
_LOG_DBG(3, "%s ret %d evt:%d\n", __func__, ret, evt);
return 0;
}
void app_wait_player_stoped(void) {
while (rb_ctl_context.status != RB_CTL_IDLE)
osThreadYield();
}
void app_wait_player_suspend(void) {
if (rb_ctl_context.status == RB_CTL_IDLE)
return;
while (rb_ctl_context.status != RB_CTL_SUSPEND)
osThreadYield();
}
void app_wait_player_resumed(void) {
if (rb_ctl_context.status == RB_CTL_IDLE)
return;
while (rb_ctl_context.status != RB_CTL_PLAYING)
osThreadYield();
}
void rb_thread_send_play(void) {
_LOG_DBG(1, " %s ", __FUNCTION__);
rb_thread_post_msg(RB_MODULE_EVT_PLAY, (uint32_t)osThreadGetId());
}
void rb_thread_send_stop(void) {
_LOG_DBG(1, " %s ", __FUNCTION__);
rb_thread_post_msg(RB_MODULE_EVT_STOP, (uint32_t)osThreadGetId());
osDelay(200);
app_wait_player_stoped();
}
void rb_thread_send_pause(void) {
_LOG_DBG(1, " %s ", __FUNCTION__);
rb_thread_post_msg(RB_MODULE_EVT_SUSPEND, (uint32_t)osThreadGetId());
app_wait_player_suspend();
_LOG_DBG(1, " %s end", __FUNCTION__);
}
void rb_thread_send_resume(void) {
_LOG_DBG(1, " %s ", __FUNCTION__);
rb_thread_post_msg(RB_MODULE_EVT_RESUME, (uint32_t)osThreadGetId());
_LOG_DBG(1, " %s end", __FUNCTION__);
}
void rb_play_dual_play_restore(uint8_t stream_type) {
_LOG_DBG(2, "%s %d \n", __func__, __LINE__);
rb_thread_post_msg(RB_MODULE_EVT_RESTORE_DUAL_PLAY, stream_type);
_LOG_DBG(2, "%s %d \n", __func__, __LINE__);
}
void rb_thread_send_switch(bool next) {
_LOG_DBG(2, "%s %d \n", __func__, __LINE__);
rb_thread_post_msg(RB_MODULE_EVT_PLAY_NEXT, next);
_LOG_DBG(2, "%s %d \n", __func__, __LINE__);
}
void rb_play_linein_start(void) {
_LOG_DBG(2, "%s %d \n", __func__, __LINE__);
rb_thread_post_msg(RB_MODULE_EVT_LINEIN_START, 0);
_LOG_DBG(2, "%s %d \n", __func__, __LINE__);
}
void rb_play_reconfig_stream(uint32_t arg) {
_LOG_DBG(3, "%s %d arg:0x%x\n", __func__, __LINE__, arg);
rb_thread_post_msg(RB_MODULE_EVT_RECONFIG_STREAM, arg);
_LOG_DBG(2, "%s %d \n", __func__, __LINE__);
}
void rb_play_set_tws_mode(uint32_t arg) {
_LOG_DBG(3, "%s %d arg:0x%x\n", __func__, __LINE__, arg);
rb_thread_post_msg(RB_MODULE_EVT_SET_TWS_MODE, arg);
_LOG_DBG(2, "%s %d \n", __func__, __LINE__);
}
void rb_thread_send_play_idx(uint32_t array_subidx) {
_LOG_DBG(2, " %s array_subidx %d, ", __FUNCTION__, array_subidx);
rb_thread_post_msg(RB_MODULE_EVT_PLAY_IDX, array_subidx);
}
void rb_thread_send_vol(bool inc) {
_LOG_DBG(2, " %s inc %d, ", __FUNCTION__, inc);
rb_thread_post_msg(RB_MODULE_EVT_CHANGE_VOL, inc);
}
void rb_thread_send_status_change(void) {
_LOG_DBG(1, " %s , ", __FUNCTION__);
rb_thread_post_msg(RB_MODULE_EVT_CHANGE_IDLE, 0);
}
void rb_thread_set_vol(uint32_t vol) {
_LOG_DBG(1, " %s , ", __FUNCTION__);
rb_thread_post_msg(RB_MODULE_EVT_SET_VOL, vol);
}
void rb_thread_send_del_file(uint16_t idx) {
_LOG_DBG(1, " %s , ", __FUNCTION__);
rb_thread_post_msg(RB_MODULE_EVT_DEL_FILE, idx);
}
void rb_thread_send_sbc_record_start(void) {
_LOG_DBG(1, " %s , ", __FUNCTION__);
rb_thread_post_msg(SBC_RECORD_ACTION_START, (uint32_t)osThreadGetId());
}
void rb_thread_send_sbc_record_data_ind(void) {
if (!rb_ctl_context.sbc_record_on)
return;
// _LOG_DBG(1," %s , ",__FUNCTION__);
rb_thread_post_msg(SBC_RECORD_ACTION_DATA_IND, (uint32_t)osThreadGetId());
}
void rb_thread_send_sbc_record_stop(void) {
_LOG_DBG(1, " %s , ", __FUNCTION__);
rb_thread_post_msg(SBC_RECORD_ACTION_STOP, (uint32_t)osThreadGetId());
}
// interface for audio module
static bool user_key_pause_stream = false;
void app_rbplay_audio_reset_pause_status(void) {
user_key_pause_stream = false;
}
int app_rbplay_audio_onoff(bool onoff, uint16_t aud_id) {
_LOG_DBG(3, " %s onoff %d, get status:%d", __FUNCTION__, onoff,
rb_ctl_get_status());
if (app_rbcodec_check_hfp_active() && !onoff) {
if (RB_CTL_PLAYING == rb_ctl_get_status()) {
rb_thread_send_pause();
}
} else if (!onoff) {
// rb_thread_send_stop();
rb_thread_send_pause();
} else {
if (!user_key_pause_stream) {
if (RB_CTL_SUSPEND == rb_ctl_get_status()) {
rb_thread_send_resume();
app_wait_player_resumed();
} else {
rb_thread_send_play();
}
}
}
return 0;
}
void app_rbplay_pause_resume(void) {
_LOG_DBG(2, " %s get status:%d", __func__, rb_ctl_get_status());
user_key_pause_stream = true;
if (RB_CTL_SUSPEND == rb_ctl_get_status()) {
user_key_pause_stream = false;
rb_thread_send_resume();
}
if (RB_CTL_PLAYING == rb_ctl_get_status()) {
user_key_pause_stream = true;
rb_thread_send_pause();
}
}
// sbc reader run within thread
static int rb_ctl_mailbox_init(void) {
rb_ctl_mailbox = osMailCreate(osMailQ(rb_ctl_mailbox), NULL);
if (rb_ctl_mailbox == NULL) {
TRACE(0, "Failed to Create rb_ctl_mailbox\n");
return -1;
}
return 0;
}
int rb_ctl_mailbox_put(RBCTL_MSG_BLOCK *msg_src) {
osStatus status;
RBCTL_MSG_BLOCK *msg_p = NULL;
msg_p = (RBCTL_MSG_BLOCK *)osMailAlloc(rb_ctl_mailbox, 0);
if (!msg_p) {
TRACE(3, "%s fail, evt:%d,arg=%d \n", __func__, msg_src->evt, msg_src->arg);
return -1;
}
ASSERT(msg_p, "osMailAlloc error");
msg_p->evt = msg_src->evt;
msg_p->arg = msg_src->arg;
status = osMailPut(rb_ctl_mailbox, msg_p);
return (int)status;
}
int rb_ctl_mailbox_free(RBCTL_MSG_BLOCK *msg_p) {
osStatus status;
status = osMailFree(rb_ctl_mailbox, msg_p);
return (int)status;
}
int rb_ctl_mailbox_get(RBCTL_MSG_BLOCK **msg_p) {
osEvent evt;
evt = osMailGet(rb_ctl_mailbox, osWaitForever);
if (evt.status == osEventMail) {
*msg_p = (RBCTL_MSG_BLOCK *)evt.value.p;
return 0;
}
return -1;
}
#if 0
void rb_ctl_action_init(void)
{
bool ind = voiceCocah_get_indication();
TRACE(2," %s Cocah %d",__func__,ind);
if( !ind) return ;
// rb_ctl_set_priority(osPriorityHigh);
rb_thread_post_msg(SBCREADER_ACTION_INIT,(uint32_t)osThreadGetId());
}
void rb_ctl_action_run(void)
{
bool ind = voiceCocah_get_indication();
TRACE(2," %s Cocah %d",__func__,ind);
if( !ind) return ;
rb_thread_post_msg(SBCREADER_ACTION_RUN,(uint32_t)osThreadGetId());
}
void rb_ctl_action_stop(void)
{
bool ind = voiceCocah_get_indication();
TRACE(2," %s Cocah %d",__func__,ind);
if( !ind) return ;
rb_thread_post_msg(SBCREADER_ACTION_STOP,(uint32_t)osThreadGetId());
}
#endif
static void rb_ctl_thread(void const *argument) {
osEvent evt;
#if 1
app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, APP_SYSFREQ_208M);
app_rbplay_load_playlist(&sd_playlist);
#endif
memset(&rb_ctl_context, 0x0, sizeof(rb_ctl_struct));
rb_ctl_context.rb_player_vol = 6;
rb_ctl_context.status = RB_CTL_IDLE;
rb_ctl_context.curr_song_idx = 0;
// load playlist here
// voiceCocah_init();
rb_ctl_context.init_done = true;
while (1) {
RBCTL_MSG_BLOCK *msg_p = NULL;
app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, APP_SYSFREQ_32K);
if (!rb_ctl_mailbox_get(&msg_p)) {
app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, APP_SYSFREQ_104M);
rb_ctl_handle_event(msg_p);
rb_ctl_mailbox_free(msg_p);
}
}
}
int rb_ctl_init(void) {
_LOG_DBG(1, "%s \n", __func__);
rb_ctl_context.init_done = false;
rb_ctl_context.sbc_record_on = false;
app_rbplay_open();
rb_ctl_mailbox_init();
rb_ctl_tid = osThreadCreate(osThread(rb_ctl_thread), NULL);
rb_ctl_default_priority = osPriorityAboveNormal;
if (rb_ctl_tid == NULL) {
TRACE(0, "Failed to Create rb_ctl_thread\n");
return 0;
}
_LOG_DBG(1, "Leave %s \n", __func__);
return 0;
}
uint8_t rb_ctl_get_vol(void) { return rb_ctl_context.rb_player_vol; }
bool rb_ctl_is_init_done(void) { return rb_ctl_context.init_done; }
bool rb_ctl_is_paused(void) { return (RB_CTL_SUSPEND == rb_ctl_get_status()); }
uint16_t rb_ctl_songs_count(void) { return sd_playlist.total_songs; }