Commit 4001a81e8e1af1e4bda63baa404a8ebb4919d1f9
1 parent
54585ffe
MusicPal mono playback support.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4332 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
29 additions
and
14 deletions
hw/musicpal.c
| @@ -230,6 +230,7 @@ static i2c_interface *mixer_i2c; | @@ -230,6 +230,7 @@ static i2c_interface *mixer_i2c; | ||
| 230 | #define MP_AUDIO_16BIT_SAMPLE (1 << 0) | 230 | #define MP_AUDIO_16BIT_SAMPLE (1 << 0) |
| 231 | #define MP_AUDIO_PLAYBACK_EN (1 << 7) | 231 | #define MP_AUDIO_PLAYBACK_EN (1 << 7) |
| 232 | #define MP_AUDIO_CLOCK_24MHZ (1 << 9) | 232 | #define MP_AUDIO_CLOCK_24MHZ (1 << 9) |
| 233 | +#define MP_AUDIO_MONO (1 << 14) | ||
| 233 | 234 | ||
| 234 | /* Wolfson 8750 I2C address */ | 235 | /* Wolfson 8750 I2C address */ |
| 235 | #define MP_WM_ADDR 0x34 | 236 | #define MP_WM_ADDR 0x34 |
| @@ -254,32 +255,46 @@ typedef struct musicpal_audio_state { | @@ -254,32 +255,46 @@ typedef struct musicpal_audio_state { | ||
| 254 | static void audio_callback(void *opaque, int free_out, int free_in) | 255 | static void audio_callback(void *opaque, int free_out, int free_in) |
| 255 | { | 256 | { |
| 256 | musicpal_audio_state *s = opaque; | 257 | musicpal_audio_state *s = opaque; |
| 257 | - int16_t *codec_buffer; | 258 | + int16_t *codec_buffer, *mem_buffer; |
| 258 | int pos, block_size; | 259 | int pos, block_size; |
| 259 | 260 | ||
| 260 | if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) | 261 | if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) |
| 261 | return; | 262 | return; |
| 262 | 263 | ||
| 263 | if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) | 264 | if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) |
| 264 | - free_out <<= 2; | ||
| 265 | - else | 265 | + free_out <<= 1; |
| 266 | + | ||
| 267 | + if (!(s->playback_mode & MP_AUDIO_MONO)) | ||
| 266 | free_out <<= 1; | 268 | free_out <<= 1; |
| 267 | 269 | ||
| 268 | block_size = s->threshold/2; | 270 | block_size = s->threshold/2; |
| 269 | if (free_out - s->last_free < block_size) | 271 | if (free_out - s->last_free < block_size) |
| 270 | return; | 272 | return; |
| 271 | 273 | ||
| 272 | - if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) | ||
| 273 | - memcpy(wm8750_dac_buffer(s->wm, block_size >> 2), | ||
| 274 | - (uint32_t *)(s->target_buffer + s->play_pos), | ||
| 275 | - block_size); | ||
| 276 | - else { | ||
| 277 | - codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1); | ||
| 278 | - for (pos = 0; pos < block_size; pos += 2) { | ||
| 279 | - *codec_buffer++ = cpu_to_le16(256 * | ||
| 280 | - *(int8_t *)(s->target_buffer + s->play_pos + pos)); | ||
| 281 | - *codec_buffer++ = cpu_to_le16(256 * | ||
| 282 | - *(int8_t *)(s->target_buffer + s->play_pos + pos + 1)); | 274 | + mem_buffer = s->target_buffer + s->play_pos; |
| 275 | + if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) { | ||
| 276 | + if (s->playback_mode & MP_AUDIO_MONO) { | ||
| 277 | + codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1); | ||
| 278 | + for (pos = 0; pos < block_size; pos += 2) { | ||
| 279 | + *codec_buffer++ = *mem_buffer; | ||
| 280 | + *codec_buffer++ = *mem_buffer++; | ||
| 281 | + } | ||
| 282 | + } else | ||
| 283 | + memcpy(wm8750_dac_buffer(s->wm, block_size >> 2), | ||
| 284 | + (uint32_t *)mem_buffer, block_size); | ||
| 285 | + } else { | ||
| 286 | + if (s->playback_mode & MP_AUDIO_MONO) { | ||
| 287 | + codec_buffer = wm8750_dac_buffer(s->wm, block_size); | ||
| 288 | + for (pos = 0; pos < block_size; pos++) { | ||
| 289 | + *codec_buffer++ = cpu_to_le16(256 * *((int8_t *)mem_buffer)); | ||
| 290 | + *codec_buffer++ = cpu_to_le16(256 * *((int8_t *)mem_buffer)++); | ||
| 291 | + } | ||
| 292 | + } else { | ||
| 293 | + codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1); | ||
| 294 | + for (pos = 0; pos < block_size; pos += 2) { | ||
| 295 | + *codec_buffer++ = cpu_to_le16(256 * *((int8_t *)mem_buffer)++); | ||
| 296 | + *codec_buffer++ = cpu_to_le16(256 * *((int8_t *)mem_buffer)++); | ||
| 297 | + } | ||
| 283 | } | 298 | } |
| 284 | } | 299 | } |
| 285 | wm8750_dac_commit(s->wm); | 300 | wm8750_dac_commit(s->wm); |