Commit 662caa6f9197a4e0d5e64743f1078ddc82836852
1 parent
c21c583a
Let WM8750 users write to audio buffer directly.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4254 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
30 additions
and
8 deletions
hw/i2c.h
| @@ -67,6 +67,8 @@ void wm8750_data_req_set(i2c_slave *i2c, | @@ -67,6 +67,8 @@ void wm8750_data_req_set(i2c_slave *i2c, | ||
| 67 | void (*data_req)(void *, int, int), void *opaque); | 67 | void (*data_req)(void *, int, int), void *opaque); |
| 68 | void wm8750_dac_dat(void *opaque, uint32_t sample); | 68 | void wm8750_dac_dat(void *opaque, uint32_t sample); |
| 69 | uint32_t wm8750_adc_dat(void *opaque); | 69 | uint32_t wm8750_adc_dat(void *opaque); |
| 70 | +void *wm8750_dac_buffer(void *opaque, int samples); | ||
| 71 | +void wm8750_dac_commit(void *opaque); | ||
| 70 | 72 | ||
| 71 | /* ssd0303.c */ | 73 | /* ssd0303.c */ |
| 72 | void ssd0303_init(DisplayState *ds, i2c_bus *bus, int address); | 74 | void ssd0303_init(DisplayState *ds, i2c_bus *bus, int address); |
hw/musicpal.c
| @@ -254,7 +254,7 @@ typedef struct musicpal_audio_state { | @@ -254,7 +254,7 @@ typedef struct musicpal_audio_state { | ||
| 254 | static void audio_callback(void *opaque, int free_out, int free_in) | 254 | static void audio_callback(void *opaque, int free_out, int free_in) |
| 255 | { | 255 | { |
| 256 | musicpal_audio_state *s = opaque; | 256 | musicpal_audio_state *s = opaque; |
| 257 | - int16_t channel[2]; | 257 | + int16_t *codec_buffer; |
| 258 | int pos, block_size; | 258 | int pos, block_size; |
| 259 | 259 | ||
| 260 | if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) | 260 | if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) |
| @@ -270,17 +270,19 @@ static void audio_callback(void *opaque, int free_out, int free_in) | @@ -270,17 +270,19 @@ static void audio_callback(void *opaque, int free_out, int free_in) | ||
| 270 | return; | 270 | return; |
| 271 | 271 | ||
| 272 | if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) | 272 | if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) |
| 273 | - for (pos = 0; pos < block_size; pos += 4) | ||
| 274 | - wm8750_dac_dat(s->wm, | ||
| 275 | - *(uint32_t *)(s->target_buffer + s->play_pos + pos)); | ||
| 276 | - else | 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); | ||
| 277 | for (pos = 0; pos < block_size; pos += 2) { | 278 | for (pos = 0; pos < block_size; pos += 2) { |
| 278 | - channel[0] = cpu_to_le16(2 * | 279 | + *codec_buffer++ = cpu_to_le16(2 * |
| 279 | *(int8_t *)(s->target_buffer + s->play_pos + pos)); | 280 | *(int8_t *)(s->target_buffer + s->play_pos + pos)); |
| 280 | - channel[1] = cpu_to_le16(2 * | 281 | + *codec_buffer++ = cpu_to_le16(2 * |
| 281 | *(int8_t *)(s->target_buffer + s->play_pos + pos + 1)); | 282 | *(int8_t *)(s->target_buffer + s->play_pos + pos + 1)); |
| 282 | - wm8750_dac_dat(s->wm, channel[0] | (channel[1] << 16)); | ||
| 283 | } | 283 | } |
| 284 | + } | ||
| 285 | + wm8750_dac_commit(s->wm); | ||
| 284 | 286 | ||
| 285 | s->last_free = free_out - block_size; | 287 | s->last_free = free_out - block_size; |
| 286 | 288 |
hw/wm8750.c
| @@ -627,6 +627,24 @@ void wm8750_dac_dat(void *opaque, uint32_t sample) | @@ -627,6 +627,24 @@ void wm8750_dac_dat(void *opaque, uint32_t sample) | ||
| 627 | wm8750_out_flush(s); | 627 | wm8750_out_flush(s); |
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | +void *wm8750_dac_buffer(void *opaque, int samples) | ||
| 631 | +{ | ||
| 632 | + struct wm8750_s *s = (struct wm8750_s *) opaque; | ||
| 633 | + /* XXX: Should check if there are <i>samples</i> free samples available */ | ||
| 634 | + void *ret = s->data_out + s->idx_out; | ||
| 635 | + | ||
| 636 | + s->idx_out += samples << 2; | ||
| 637 | + s->req_out -= samples << 2; | ||
| 638 | + return ret; | ||
| 639 | +} | ||
| 640 | + | ||
| 641 | +void wm8750_dac_commit(void *opaque) | ||
| 642 | +{ | ||
| 643 | + struct wm8750_s *s = (struct wm8750_s *) opaque; | ||
| 644 | + | ||
| 645 | + return wm8750_out_flush(s); | ||
| 646 | +} | ||
| 647 | + | ||
| 630 | uint32_t wm8750_adc_dat(void *opaque) | 648 | uint32_t wm8750_adc_dat(void *opaque) |
| 631 | { | 649 | { |
| 632 | struct wm8750_s *s = (struct wm8750_s *) opaque; | 650 | struct wm8750_s *s = (struct wm8750_s *) opaque; |