Automatic choice of playback frequency by the playing file properties
Change-Id: I0fdc5d32225decbf051685be819be8df84171998
This commit is contained in:
parent
e0bb30a1bd
commit
e0bcb0f2bc
2 changed files with 78 additions and 9 deletions
|
@ -35,6 +35,9 @@
|
||||||
#include "talk.h"
|
#include "talk.h"
|
||||||
#include "playlist.h"
|
#include "playlist.h"
|
||||||
#include "abrepeat.h"
|
#include "abrepeat.h"
|
||||||
|
#ifdef HAVE_PLAY_FREQ
|
||||||
|
#include "pcm_mixer.h"
|
||||||
|
#endif
|
||||||
#include "pcmbuf.h"
|
#include "pcmbuf.h"
|
||||||
#include "audio_thread.h"
|
#include "audio_thread.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
|
@ -335,6 +338,7 @@ enum audio_start_playback_flags
|
||||||
{
|
{
|
||||||
AUDIO_START_RESTART = 0x1, /* "Restart" playback (flush _all_ tracks) */
|
AUDIO_START_RESTART = 0x1, /* "Restart" playback (flush _all_ tracks) */
|
||||||
AUDIO_START_NEWBUF = 0x2, /* Mark the audiobuffer as invalid */
|
AUDIO_START_NEWBUF = 0x2, /* Mark the audiobuffer as invalid */
|
||||||
|
AUDIO_START_REFRESH = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
static void audio_start_playback(const struct audio_resume_info *resume_info,
|
static void audio_start_playback(const struct audio_resume_info *resume_info,
|
||||||
|
@ -2586,10 +2590,23 @@ static void audio_on_track_changed(void)
|
||||||
static void audio_start_playback(const struct audio_resume_info *resume_info,
|
static void audio_start_playback(const struct audio_resume_info *resume_info,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
struct audio_resume_info resume =
|
static struct audio_resume_info resume = { 0, 0 };
|
||||||
*(resume_info ?: &(struct audio_resume_info){ 0, 0 } );
|
|
||||||
enum play_status old_status = play_status;
|
enum play_status old_status = play_status;
|
||||||
|
|
||||||
|
if (!(flags & AUDIO_START_REFRESH))
|
||||||
|
{
|
||||||
|
if (resume_info)
|
||||||
|
{
|
||||||
|
resume.elapsed = resume_info->elapsed;
|
||||||
|
resume.offset = resume_info->offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resume.elapsed = 0;
|
||||||
|
resume.offset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & AUDIO_START_NEWBUF)
|
if (flags & AUDIO_START_NEWBUF)
|
||||||
{
|
{
|
||||||
/* Mark the buffer dirty - if not playing, it will be reset next
|
/* Mark the buffer dirty - if not playing, it will be reset next
|
||||||
|
@ -2613,8 +2630,13 @@ static void audio_start_playback(const struct audio_resume_info *resume_info,
|
||||||
/* Clear out some stuff to resume the current track where it
|
/* Clear out some stuff to resume the current track where it
|
||||||
left off */
|
left off */
|
||||||
pcmbuf_play_stop();
|
pcmbuf_play_stop();
|
||||||
resume.elapsed = id3_get(PLAYING_ID3)->elapsed;
|
|
||||||
resume.offset = id3_get(PLAYING_ID3)->offset;
|
if (!(flags & AUDIO_START_REFRESH))
|
||||||
|
{
|
||||||
|
resume.elapsed = id3_get(PLAYING_ID3)->elapsed;
|
||||||
|
resume.offset = id3_get(PLAYING_ID3)->offset;
|
||||||
|
}
|
||||||
|
|
||||||
track_list_clear(TRACK_LIST_CLEAR_ALL);
|
track_list_clear(TRACK_LIST_CLEAR_ALL);
|
||||||
pcmbuf_update_frequency();
|
pcmbuf_update_frequency();
|
||||||
}
|
}
|
||||||
|
@ -2629,6 +2651,7 @@ static void audio_start_playback(const struct audio_resume_info *resume_info,
|
||||||
pcmbuf_start_track_change(TRACK_CHANGE_MANUAL);
|
pcmbuf_start_track_change(TRACK_CHANGE_MANUAL);
|
||||||
wipe_track_metadata(true);
|
wipe_track_metadata(true);
|
||||||
}
|
}
|
||||||
|
pcmbuf_update_frequency();
|
||||||
|
|
||||||
/* Set after track finish event in case skip was in progress */
|
/* Set after track finish event in case skip was in progress */
|
||||||
skip_pending = TRACK_SKIP_NONE;
|
skip_pending = TRACK_SKIP_NONE;
|
||||||
|
@ -3220,7 +3243,7 @@ void audio_playback_handler(struct queue_event *ev)
|
||||||
case Q_AUDIO_REMAKE_AUDIO_BUFFER:
|
case Q_AUDIO_REMAKE_AUDIO_BUFFER:
|
||||||
/* buffer needs to be reinitialized */
|
/* buffer needs to be reinitialized */
|
||||||
LOGFQUEUE("playback < Q_AUDIO_REMAKE_AUDIO_BUFFER");
|
LOGFQUEUE("playback < Q_AUDIO_REMAKE_AUDIO_BUFFER");
|
||||||
audio_start_playback(NULL, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
|
audio_start_playback(NULL, AUDIO_START_RESTART | AUDIO_START_NEWBUF | (ev->data ? AUDIO_START_REFRESH : 0));
|
||||||
if (play_status == PLAY_STOPPED)
|
if (play_status == PLAY_STOPPED)
|
||||||
return; /* just need to change buffer state */
|
return; /* just need to change buffer state */
|
||||||
break;
|
break;
|
||||||
|
@ -3795,15 +3818,57 @@ void audio_set_crossfade(int enable)
|
||||||
#endif /* HAVE_CROSSFADE */
|
#endif /* HAVE_CROSSFADE */
|
||||||
|
|
||||||
#ifdef HAVE_PLAY_FREQ
|
#ifdef HAVE_PLAY_FREQ
|
||||||
|
static unsigned long audio_guess_frequency(struct mp3entry *id3)
|
||||||
|
{
|
||||||
|
return (id3->frequency % 4000) ? SAMPR_44 : SAMPR_48;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void audio_change_frequency_callback(unsigned short id, void *data)
|
||||||
|
{
|
||||||
|
static bool starting_playback = false;
|
||||||
|
struct mp3entry *id3;
|
||||||
|
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case PLAYBACK_EVENT_START_PLAYBACK:
|
||||||
|
starting_playback = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYBACK_EVENT_TRACK_CHANGE:
|
||||||
|
id3 = ((struct track_event *)data)->id3;
|
||||||
|
if (id3 && !global_settings.play_frequency)
|
||||||
|
{
|
||||||
|
unsigned long guessed_frequency = audio_guess_frequency(id3);
|
||||||
|
if (mixer_get_frequency() != guessed_frequency)
|
||||||
|
{
|
||||||
|
#ifdef PLAYBACK_VOICE
|
||||||
|
voice_stop();
|
||||||
|
#endif
|
||||||
|
mixer_set_frequency(guessed_frequency);
|
||||||
|
audio_queue_post(Q_AUDIO_REMAKE_AUDIO_BUFFER, starting_playback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
starting_playback = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void audio_set_playback_frequency(int setting)
|
void audio_set_playback_frequency(int setting)
|
||||||
{
|
{
|
||||||
static const unsigned long play_sampr[] = { SAMPR_44, SAMPR_48 };
|
static const unsigned long play_sampr[] = { SAMPR_44, SAMPR_48 };
|
||||||
|
|
||||||
if ((unsigned)setting >= ARRAYLEN(play_sampr))
|
if ((unsigned)setting > ARRAYLEN(play_sampr)) /* [0] is "automatic" */
|
||||||
setting = 0;
|
setting = 0;
|
||||||
|
|
||||||
unsigned long playback_sampr = mixer_get_frequency();
|
unsigned long playback_sampr = mixer_get_frequency();
|
||||||
unsigned long sampr = play_sampr[setting];
|
unsigned long sampr = setting ?
|
||||||
|
play_sampr[setting - 1] :
|
||||||
|
((audio_status() == AUDIO_STATUS_PLAY) ?
|
||||||
|
audio_guess_frequency(audio_current_track()) :
|
||||||
|
playback_sampr);
|
||||||
|
|
||||||
if (sampr != playback_sampr)
|
if (sampr != playback_sampr)
|
||||||
{
|
{
|
||||||
|
@ -3829,6 +3894,10 @@ void INIT_ATTR playback_init(void)
|
||||||
track_list_init();
|
track_list_init();
|
||||||
buffering_init();
|
buffering_init();
|
||||||
pcmbuf_update_frequency();
|
pcmbuf_update_frequency();
|
||||||
|
#ifdef HAVE_PLAY_FREQ
|
||||||
|
add_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_change_frequency_callback);
|
||||||
|
add_event(PLAYBACK_EVENT_START_PLAYBACK, audio_change_frequency_callback);
|
||||||
|
#endif
|
||||||
#ifdef HAVE_CROSSFADE
|
#ifdef HAVE_CROSSFADE
|
||||||
/* Set crossfade setting for next buffer init which should be about... */
|
/* Set crossfade setting for next buffer init which should be about... */
|
||||||
pcmbuf_request_crossfade_enable(global_settings.crossfade);
|
pcmbuf_request_crossfade_enable(global_settings.crossfade);
|
||||||
|
|
|
@ -867,8 +867,8 @@ const struct settings_list settings[] = {
|
||||||
), /* CHOICE_SETTING( repeat_mode ) */
|
), /* CHOICE_SETTING( repeat_mode ) */
|
||||||
#ifdef HAVE_PLAY_FREQ
|
#ifdef HAVE_PLAY_FREQ
|
||||||
STRINGCHOICE_SETTING(0, play_frequency, LANG_FREQUENCY, 0,
|
STRINGCHOICE_SETTING(0, play_frequency, LANG_FREQUENCY, 0,
|
||||||
"playback frequency", "44.1 kHz,48 kHz", NULL, 2,
|
"playback frequency", "auto,44.1 kHz,48 kHz", NULL, 3,
|
||||||
TALK_ID_DECIMAL(441, 1, UNIT_KHZ), TALK_ID(48, UNIT_KHZ)),
|
LANG_AUTOMATIC, TALK_ID_DECIMAL(441, 1, UNIT_KHZ), TALK_ID(48, UNIT_KHZ)),
|
||||||
#endif /* HAVE_PLAY_FREQ */
|
#endif /* HAVE_PLAY_FREQ */
|
||||||
/* LCD */
|
/* LCD */
|
||||||
#ifdef HAVE_LCD_CONTRAST
|
#ifdef HAVE_LCD_CONTRAST
|
||||||
|
|
Loading…
Reference in a new issue