/* * Copyright (c) 2016 Actions Semi Co., Inc. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief audio system. */ #include #include #include #include #include #include #include #include #include #include #include #include #define SYS_LOG_NO_NEWLINE #ifdef SYS_LOG_DOMAIN #undef SYS_LOG_DOMAIN #endif #define SYS_LOG_DOMAIN "audio system" struct audio_system_t *audio_system; int audio_system_set_output_sample_rate(int value) { if (!audio_system) return -ESRCH; audio_system->output_sample_rate = value; return 0; } int audio_system_get_output_sample_rate(void) { if (!audio_system) return -ESRCH; return audio_system->output_sample_rate; } int audio_system_get_output_framecount(void) { if (!audio_system) return -ESRCH; return 0; } int audio_system_set_master_volume(int value) { if (!audio_system) return -ESRCH; audio_system->master_volume = value; return audio_system_set_stream_volume(AUDIO_STREAM_DEFAULT, value); } int audio_system_get_master_volume(void) { if (!audio_system) return -ESRCH; return audio_system->master_volume; } int audio_system_set_master_mute(int value) { if (!audio_system) return -ESRCH; audio_system->master_muted = value; /**TODO set master mute */ return 0; } int audio_system_get_master_mute(void) { if (!audio_system) return -ESRCH; return audio_system->master_muted; } int audio_system_set_stream_mute(int stream_type, int mute) { struct audio_track_t *audio_track = NULL; int ret = -ESRCH; if (!audio_system) return -ESRCH; for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { audio_track = audio_system->audio_track_pool[i]; if (audio_track && audio_track->stream_type == stream_type) { ret = audio_track_set_mute(audio_track, mute); } } return ret; } int audio_system_get_stream_mute(int stream_type) { struct audio_track_t *audio_track = NULL; int ret = -ESRCH; if (!audio_system) return -ESRCH; for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { audio_track = audio_system->audio_track_pool[i]; if (audio_track && audio_track->stream_type == stream_type) { ret = audio_track_get_volume(audio_track); break; } } return (ret == 0) ? 1 : 0; } int audio_system_mute_microphone(int value) { struct audio_record_t *audio_record = NULL; if (!audio_system) return -ESRCH; audio_system->microphone_muted = value; for (int i = 0; i < MAX_AUDIO_RECORD_NUM; i++) { audio_record = audio_system->audio_record_pool[i]; if (audio_record) { audio_record->muted = audio_system->microphone_muted; } } return 0; } int audio_system_get_microphone_muted(void) { if (!audio_system) return -ESRCH; return audio_system->microphone_muted ? 1 : 0; } int audio_system_register_track(struct audio_track_t *audio_track) { if (!audio_system) return -ESRCH; for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { if (!audio_system->audio_track_pool[i]) { audio_system->audio_track_pool[i] = audio_track; audio_system->audio_track_num++; SYS_LOG_INF(" %p index %d\n", audio_track, i); break; } } return 0; } int audio_system_mutex_lock(void) { if (!audio_system) return -ESRCH; return os_mutex_lock(&audio_system->audio_system_mutex, OS_FOREVER); } int audio_system_mutex_unlock(void) { if (!audio_system) return -ESRCH; os_mutex_unlock(&audio_system->audio_system_mutex); return 0; } struct audio_track_t *audio_system_get_track(void) { if (!audio_system) return NULL; for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { if (audio_system->audio_track_pool[i]) { return audio_system->audio_track_pool[i]; } } return NULL; } int audio_system_unregister_track(struct audio_track_t *audio_track) { int ret = -ENXIO; if (!audio_system) return -ESRCH; for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { if (audio_system->audio_track_pool[i] == audio_track) { audio_system->audio_track_pool[i] = NULL; audio_system->audio_track_num--; SYS_LOG_INF(" %p index %d\n", audio_track, i); ret = 0; break; } } for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { struct audio_track_t *tmp_track = NULL; tmp_track = audio_system->audio_track_pool[i]; if (tmp_track) audio_system_set_stream_volume(tmp_track->stream_type, tmp_track->volume); } return 0; } int audio_system_register_record(struct audio_record_t *audio_record) { int ret = -EAGAIN; if (!audio_system) return -ESRCH; for (int i = 0; i < MAX_AUDIO_RECORD_NUM; i++) { if (!audio_system->audio_record_pool[i]) { audio_system->audio_record_pool[i] = audio_record; audio_system->audio_record_num++; SYS_LOG_INF(" %p index %d\n", audio_record, i); ret = 0; break; } } return ret; } int audio_system_unregister_record(struct audio_record_t *audio_record) { int ret = -ENXIO; if (!audio_system) return -ESRCH; for (int i = 0; i < MAX_AUDIO_RECORD_NUM; i++) { if (audio_system->audio_record_pool[i] == audio_record) { audio_system->audio_record_pool[i] = NULL; SYS_LOG_INF(" %p index %d\n", audio_record, i); audio_system->audio_record_num--; ret = 0; break; } } return ret; } static void _audio_system_get_volume_config(const char *name, uint8_t *volume) { #ifdef CONFIG_PROPERTY char temp[8]; memset(temp, 0, sizeof(temp)); int ret = property_get(name, temp, sizeof(temp)); if (ret >= 0) { *volume = atoi(temp); } else { *volume = DEFAULT_VOLUME; } SYS_LOG_INF(" %s %d\n", name, *volume); #endif } static int _audio_system_save_volume(const char *name, uint8_t volume) { char temp[5]; if (!audio_policy_check_save_volume_to_nvram()) { return 0; } snprintf(temp, sizeof(temp), "%d", volume); #ifdef CONFIG_PROPERTY return property_set(name, temp, strlen(temp) + 1); #else return 0; #endif } int audio_system_set_stream_volume(int stream_type, int volume) { struct audio_track_t *audio_track = NULL; int ret = 0; if (!audio_system) return -ESRCH; if (volume >= audio_policy_get_volume_level()) { volume = audio_policy_get_volume_level(); ret = MAX_VOLUME_VALUE; } /**usound default used 16 level */ if (stream_type == AUDIO_STREAM_USOUND) { if (volume >= 16) { volume = 16; ret = MAX_VOLUME_VALUE; } } if (volume <= 0) { ret = MIN_VOLUME_VALUE; volume = 0; } os_mutex_lock(&audio_system->audio_system_mutex, OS_FOREVER); for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { audio_track = audio_system->audio_track_pool[i]; if (audio_track && (audio_track->stream_type == stream_type || stream_type == AUDIO_STREAM_DEFAULT)) { audio_track_set_volume(audio_track, volume); } } os_mutex_unlock(&audio_system->audio_system_mutex); if (stream_type == AUDIO_STREAM_VOICE) { audio_system->voice_volume = volume; _audio_system_save_volume(CFG_BTCALL_VOLUME, volume); } if (stream_type == AUDIO_STREAM_MUSIC || stream_type == AUDIO_STREAM_DEFAULT) { audio_system->music_volume = volume; _audio_system_save_volume(CFG_BTPLAY_VOLUME, volume); } if (stream_type == AUDIO_STREAM_LINEIN || stream_type == AUDIO_STREAM_DEFAULT) { audio_system->linein_volume = volume; _audio_system_save_volume(CFG_LINEIN_VOLUME, volume); } if (stream_type == AUDIO_STREAM_USOUND || stream_type == AUDIO_STREAM_DEFAULT) { audio_system->usound_volume = volume; _audio_system_save_volume(CFG_USOUND_VOLUME, volume); } if (stream_type == AUDIO_STREAM_LOCAL_MUSIC || stream_type == AUDIO_STREAM_DEFAULT) { audio_system->lcmusic_volume = volume; _audio_system_save_volume(CFG_LOCALPLAY_VOLUME, volume); } if (stream_type == AUDIO_STREAM_FM || stream_type == AUDIO_STREAM_DEFAULT) { audio_system->fm_volume = volume; _audio_system_save_volume(CFG_FM_VOLUME, volume); } if (stream_type == AUDIO_STREAM_I2SRX_IN || stream_type == AUDIO_STREAM_DEFAULT) { audio_system->i2srx_in_volume = volume; _audio_system_save_volume(CFG_I2SRX_IN_VOLUME, volume); } if (stream_type == AUDIO_STREAM_MIC_IN || stream_type == AUDIO_STREAM_DEFAULT) { audio_system->mic_in_volume = volume; _audio_system_save_volume(CFG_MIC_IN_VOLUME, volume); } if (stream_type == AUDIO_STREAM_SPDIF_IN || stream_type == AUDIO_STREAM_DEFAULT) { audio_system->spidf_in_volume = volume; _audio_system_save_volume(CFG_SPDIF_IN_VOLUME, volume); } if (stream_type != AUDIO_STREAM_VOICE) { audio_system->master_volume = volume; if (volume < audio_system->min_volume) volume = audio_system->min_volume; if(volume > audio_system->max_volume) volume = audio_system->max_volume; if (!audio_policy_check_tts_fixed_volume()) { audio_system->tts_volume = volume; _audio_system_save_volume(CFG_TONE_VOLUME, volume); } } SYS_LOG_INF("volume: %d %d ret %d ok\n", volume, stream_type, ret); return ret; } int audio_system_get_current_volume(int stream_type) { int volume = 0; struct audio_track_t *audio_track = NULL; if (!audio_system) return -ESRCH; volume = audio_system_get_stream_volume(stream_type); /**make sure tts have volume*/ for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { audio_track = audio_system->audio_track_pool[i]; if ((audio_track->stream_type == AUDIO_STREAM_TTS) || (audio_track->stream_type == AUDIO_STREAM_TIP)) { if (volume != audio_system->tts_volume) { volume = audio_system->tts_volume; } } } return volume; } int audio_system_get_current_pa_volume(int stream_type) { int volume = 0; int pa_volume = 0; struct audio_track_t *audio_track = NULL; if (!audio_system) return -ESRCH; volume = audio_system_get_current_volume(stream_type); pa_volume = audio_policy_get_pa_volume(stream_type, volume); /**make sure tts have volume*/ for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { audio_track = audio_system->audio_track_pool[i]; if ((audio_track->stream_type == AUDIO_STREAM_TTS) || (audio_track->stream_type == AUDIO_STREAM_TIP)) { pa_volume = audio_policy_get_pa_volume(AUDIO_STREAM_TTS, volume); } } return pa_volume; } int audio_system_get_stream_volume(int stream_type) { int volume = 0; if (!audio_system) return -ESRCH; switch (stream_type) { case AUDIO_STREAM_MUSIC: volume = audio_system->music_volume; break; case AUDIO_STREAM_TTS: case AUDIO_STREAM_TIP: volume = audio_system->tts_volume; break; case AUDIO_STREAM_VOICE: volume = audio_system->voice_volume; break; case AUDIO_STREAM_LINEIN: volume = audio_system->linein_volume; break; case AUDIO_STREAM_USOUND: volume = audio_system->usound_volume; break; case AUDIO_STREAM_LOCAL_MUSIC: volume = audio_system->lcmusic_volume; break; case AUDIO_STREAM_FM: volume = audio_system->fm_volume; break; case AUDIO_STREAM_I2SRX_IN: volume = audio_system->i2srx_in_volume; break; case AUDIO_STREAM_SPDIF_IN: volume = audio_system->spidf_in_volume; break; default: volume = audio_system->master_volume; break; } return volume; } int audio_system_set_stream_pa_volume(int stream_type, int volume) { struct audio_track_t *audio_track = NULL; if (!audio_system) return -ESRCH; os_mutex_lock(&audio_system->audio_system_mutex, OS_FOREVER); for (int i = 0; i < MAX_AUDIO_TRACK_NUM; i++) { audio_track = audio_system->audio_track_pool[i]; if (audio_track && (audio_track->stream_type == stream_type || stream_type == AUDIO_STREAM_DEFAULT)) { audio_track_set_pa_volume(audio_track, volume); } } os_mutex_unlock(&audio_system->audio_system_mutex); return 0; } int audio_system_set_microphone_volume(int stream_type, int volume) { struct audio_record_t *audio_record = NULL; int ret = 0; if (!audio_system) return -ESRCH; for (int i = 0; i < MAX_AUDIO_RECORD_NUM; i++) { audio_record = audio_system->audio_record_pool[i]; if (audio_record) { audio_record_set_volume(audio_record, volume); } } SYS_LOG_INF("volume: %d ret %d ok\n", volume, ret); return ret; } int audio_system_get_max_volume(void) { return audio_system->max_volume; } int audio_system_get_min_volume(void) { return audio_system->min_volume; } static struct audio_system_t global_audio_system; int aduio_system_init(void) { audio_system = &global_audio_system; memset(audio_system, 0, sizeof(struct audio_system_t)); os_mutex_init(&audio_system->audio_system_mutex); _audio_system_get_volume_config(CFG_BTPLAY_VOLUME, &audio_system->music_volume); audio_system->master_volume = audio_system->music_volume; _audio_system_get_volume_config(CFG_TONE_VOLUME, &audio_system->tts_volume); _audio_system_get_volume_config(CFG_BTCALL_VOLUME, &audio_system->voice_volume); _audio_system_get_volume_config(CFG_LINEIN_VOLUME, &audio_system->linein_volume); _audio_system_get_volume_config(CFG_USOUND_VOLUME, &audio_system->usound_volume); _audio_system_get_volume_config(CFG_LOCALPLAY_VOLUME, &audio_system->lcmusic_volume); _audio_system_get_volume_config(CFG_FM_VOLUME, &audio_system->fm_volume); _audio_system_get_volume_config(CFG_I2SRX_IN_VOLUME, &audio_system->i2srx_in_volume); _audio_system_get_volume_config(CFG_SPDIF_IN_VOLUME, &audio_system->spidf_in_volume); _audio_system_get_volume_config(CFG_TTS_MIN_VOL, &audio_system->min_volume); _audio_system_get_volume_config(CFG_TTS_MAX_VOL, &audio_system->max_volume); /* audio_system_set_output_sample_rate(48); */ #if CONFIG_AUDIO_ACTS /* init audio hal */ hal_audio_out_init(); hal_audio_in_init(); #endif /* audio_flinger_init(); */ return 0; }