834 lines
22 KiB
C++
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; }
|