diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/musicpal.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/hw/musicpal.c b/hw/musicpal.c index 34e7d1119e..e6ecb5a126 100644 --- a/hw/musicpal.c +++ b/hw/musicpal.c @@ -230,6 +230,7 @@ static i2c_interface *mixer_i2c; #define MP_AUDIO_16BIT_SAMPLE (1 << 0) #define MP_AUDIO_PLAYBACK_EN (1 << 7) #define MP_AUDIO_CLOCK_24MHZ (1 << 9) +#define MP_AUDIO_MONO (1 << 14) /* Wolfson 8750 I2C address */ #define MP_WM_ADDR 0x34 @@ -254,32 +255,46 @@ typedef struct musicpal_audio_state { static void audio_callback(void *opaque, int free_out, int free_in) { musicpal_audio_state *s = opaque; - int16_t *codec_buffer; + int16_t *codec_buffer, *mem_buffer; int pos, block_size; if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) return; if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) - free_out <<= 2; - else + free_out <<= 1; + + if (!(s->playback_mode & MP_AUDIO_MONO)) free_out <<= 1; block_size = s->threshold/2; if (free_out - s->last_free < block_size) return; - if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) - memcpy(wm8750_dac_buffer(s->wm, block_size >> 2), - (uint32_t *)(s->target_buffer + s->play_pos), - block_size); - else { - codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1); - for (pos = 0; pos < block_size; pos += 2) { - *codec_buffer++ = cpu_to_le16(256 * - *(int8_t *)(s->target_buffer + s->play_pos + pos)); - *codec_buffer++ = cpu_to_le16(256 * - *(int8_t *)(s->target_buffer + s->play_pos + pos + 1)); + mem_buffer = s->target_buffer + s->play_pos; + if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) { + if (s->playback_mode & MP_AUDIO_MONO) { + codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1); + for (pos = 0; pos < block_size; pos += 2) { + *codec_buffer++ = *mem_buffer; + *codec_buffer++ = *mem_buffer++; + } + } else + memcpy(wm8750_dac_buffer(s->wm, block_size >> 2), + (uint32_t *)mem_buffer, block_size); + } else { + if (s->playback_mode & MP_AUDIO_MONO) { + codec_buffer = wm8750_dac_buffer(s->wm, block_size); + for (pos = 0; pos < block_size; pos++) { + *codec_buffer++ = cpu_to_le16(256 * *((int8_t *)mem_buffer)); + *codec_buffer++ = cpu_to_le16(256 * *((int8_t *)mem_buffer)++); + } + } else { + codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1); + for (pos = 0; pos < block_size; pos += 2) { + *codec_buffer++ = cpu_to_le16(256 * *((int8_t *)mem_buffer)++); + *codec_buffer++ = cpu_to_le16(256 * *((int8_t *)mem_buffer)++); + } } } wm8750_dac_commit(s->wm); |