diff options
Diffstat (limited to 'firmware/target/hosted/pcm-alsa.c')
-rw-r--r-- | firmware/target/hosted/pcm-alsa.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/firmware/target/hosted/pcm-alsa.c b/firmware/target/hosted/pcm-alsa.c index 3d91bc18cf..428902b82e 100644 --- a/firmware/target/hosted/pcm-alsa.c +++ b/firmware/target/hosted/pcm-alsa.c | |||
@@ -81,8 +81,8 @@ static const snd_pcm_format_t format = SND_PCM_FORMAT_S16; /* sample format * | |||
81 | typedef short sample_t; | 81 | typedef short sample_t; |
82 | #endif | 82 | #endif |
83 | static const int channels = 2; /* count of channels */ | 83 | static const int channels = 2; /* count of channels */ |
84 | static unsigned int sample_rate = 0; | ||
85 | static unsigned int real_sample_rate = 0; | 84 | static unsigned int real_sample_rate = 0; |
85 | static unsigned int last_sample_rate = 0; | ||
86 | 86 | ||
87 | static snd_pcm_t *handle = NULL; | 87 | static snd_pcm_t *handle = NULL; |
88 | static snd_pcm_sframes_t buffer_size; | 88 | static snd_pcm_sframes_t buffer_size; |
@@ -148,17 +148,17 @@ static int set_hwparams(snd_pcm_t *handle) | |||
148 | goto error; | 148 | goto error; |
149 | } | 149 | } |
150 | /* set the stream rate */ | 150 | /* set the stream rate */ |
151 | sample_rate = srate = pcm_sampr; | 151 | srate = pcm_sampr; |
152 | err = snd_pcm_hw_params_set_rate_near(handle, params, &srate, 0); | 152 | err = snd_pcm_hw_params_set_rate_near(handle, params, &srate, 0); |
153 | if (err < 0) | 153 | if (err < 0) |
154 | { | 154 | { |
155 | logf("Rate %iHz not available for playback: %s\n", sample_rate, snd_strerror(err)); | 155 | logf("Rate %iHz not available for playback: %s\n", pcm_sampr, snd_strerror(err)); |
156 | goto error; | 156 | goto error; |
157 | } | 157 | } |
158 | real_sample_rate = srate; | 158 | real_sample_rate = srate; |
159 | if (real_sample_rate != sample_rate) | 159 | if (real_sample_rate != pcm_sampr) |
160 | { | 160 | { |
161 | logf("Rate doesn't match (requested %iHz, get %iHz)\n", sample_rate, real_sample_rate); | 161 | logf("Rate doesn't match (requested %iHz, get %iHz)\n", pcm_sampr, real_sample_rate); |
162 | err = -EINVAL; | 162 | err = -EINVAL; |
163 | goto error; | 163 | goto error; |
164 | } | 164 | } |
@@ -517,11 +517,13 @@ void pcm_play_unlock(void) | |||
517 | 517 | ||
518 | static void pcm_dma_apply_settings_nolock(void) | 518 | static void pcm_dma_apply_settings_nolock(void) |
519 | { | 519 | { |
520 | logf("PCM DMA Settings %d %d", sample_rate, pcm_sampr); | 520 | logf("PCM DMA Settings %d %d", last_sample_rate, pcm_sampr); |
521 | 521 | ||
522 | if (sample_rate != pcm_sampr) | 522 | if (last_sample_rate != pcm_sampr) |
523 | { | 523 | { |
524 | #ifdef AUDIOHW_MUTE_ON_PAUSE | 524 | last_sample_rate = pcm_sampr; |
525 | |||
526 | #ifdef AUDIOHW_MUTE_ON_SRATE_CHANGE | ||
525 | // XXX AK4450 (xDuoo X3ii) needs to be muted when switching rates. | 527 | // XXX AK4450 (xDuoo X3ii) needs to be muted when switching rates. |
526 | audiohw_mute(true); | 528 | audiohw_mute(true); |
527 | #endif | 529 | #endif |
@@ -531,8 +533,10 @@ static void pcm_dma_apply_settings_nolock(void) | |||
531 | /* Sony NWZ linux driver uses a nonstandard mecanism to set the sampling rate */ | 533 | /* Sony NWZ linux driver uses a nonstandard mecanism to set the sampling rate */ |
532 | audiohw_set_frequency(pcm_sampr); | 534 | audiohw_set_frequency(pcm_sampr); |
533 | #endif | 535 | #endif |
534 | 536 | #ifdef AUDIOHW_MUTE_ON_SRATE_CHANGE | |
535 | /* (Will be unmuted by pcm resuming) */ | 537 | audiohw_mute(false); |
538 | #endif | ||
539 | /* (Will be unmuted by pcm resuming) */ | ||
536 | } | 540 | } |
537 | } | 541 | } |
538 | 542 | ||
@@ -560,7 +564,7 @@ void pcm_play_dma_stop(void) | |||
560 | snd_pcm_nonblock(handle, 0); | 564 | snd_pcm_nonblock(handle, 0); |
561 | snd_pcm_drain(handle); | 565 | snd_pcm_drain(handle); |
562 | snd_pcm_nonblock(handle, 1); | 566 | snd_pcm_nonblock(handle, 1); |
563 | sample_rate = 0; | 567 | last_sample_rate = 0; |
564 | #ifdef AUDIOHW_MUTE_ON_PAUSE | 568 | #ifdef AUDIOHW_MUTE_ON_PAUSE |
565 | audiohw_mute(true); | 569 | audiohw_mute(true); |
566 | #endif | 570 | #endif |
@@ -575,6 +579,10 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
575 | pcm_data = addr; | 579 | pcm_data = addr; |
576 | pcm_size = size; | 580 | pcm_size = size; |
577 | 581 | ||
582 | #if !defined(AUDIOHW_MUTE_ON_PAUSE) || !defined(AUDIOHW_MUTE_ON_SRATE_CHANGE) | ||
583 | audiohw_mute(false); | ||
584 | #endif | ||
585 | |||
578 | while (1) | 586 | while (1) |
579 | { | 587 | { |
580 | snd_pcm_state_t state = snd_pcm_state(handle); | 588 | snd_pcm_state_t state = snd_pcm_state(handle); |
@@ -605,14 +613,14 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
605 | int err = async_rw(handle); | 613 | int err = async_rw(handle); |
606 | if (err < 0) { | 614 | if (err < 0) { |
607 | logf("Start error: %s\n", snd_strerror(err)); | 615 | logf("Start error: %s\n", snd_strerror(err)); |
608 | return; | 616 | return; |
609 | } | 617 | } |
610 | #ifdef AUDIOHW_MUTE_ON_PAUSE | 618 | #ifdef AUDIOHW_MUTE_ON_PAUSE |
611 | audiohw_mute(false); | 619 | audiohw_mute(false); |
612 | #endif | 620 | #endif |
613 | if (err == 0) | 621 | if (err == 0) |
614 | return; | 622 | return; |
615 | break; | 623 | break; |
616 | } | 624 | } |
617 | case SND_PCM_STATE_PAUSED: | 625 | case SND_PCM_STATE_PAUSED: |
618 | { /* paused, simply resume */ | 626 | { /* paused, simply resume */ |