Commit 8ead62cfc21f61a32677892c721674e06e9f6153

Authored by bellard
1 parent feea13e1

audio fixes + initial audio capture support (malc)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2040 c046a42c-6fe2-441c-8c8c-71466251a162
audio/alsaaudio.c
@@ -61,8 +61,8 @@ static struct { @@ -61,8 +61,8 @@ static struct {
61 .size_in_usec_in = 1, 61 .size_in_usec_in = 1,
62 .size_in_usec_out = 1, 62 .size_in_usec_out = 1,
63 #endif 63 #endif
64 - .pcm_name_out = "hw:0,0",  
65 - .pcm_name_in = "hw:0,0", 64 + .pcm_name_out = "default",
  65 + .pcm_name_in = "default",
66 #ifdef HIGH_LATENCY 66 #ifdef HIGH_LATENCY
67 .buffer_size_in = 400000, 67 .buffer_size_in = 400000,
68 .period_size_in = 400000 / 4, 68 .period_size_in = 400000 / 4,
@@ -606,7 +606,6 @@ static int alsa_run_out (HWVoiceOut *hw) @@ -606,7 +606,6 @@ static int alsa_run_out (HWVoiceOut *hw)
606 } 606 }
607 } 607 }
608 608
609 - mixeng_clear (src, written);  
610 rpos = (rpos + written) % hw->samples; 609 rpos = (rpos + written) % hw->samples;
611 samples -= written; 610 samples -= written;
612 len -= written; 611 len -= written;
audio/audio.c
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 /* #define DEBUG_PLIVE */ 29 /* #define DEBUG_PLIVE */
30 /* #define DEBUG_LIVE */ 30 /* #define DEBUG_LIVE */
31 /* #define DEBUG_OUT */ 31 /* #define DEBUG_OUT */
  32 +/* #define DEBUG_CAPTURE */
32 33
33 #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown" 34 #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
34 35
@@ -137,7 +138,7 @@ int audio_bug (const char *funcname, int cond) @@ -137,7 +138,7 @@ int audio_bug (const char *funcname, int cond)
137 if (cond) { 138 if (cond) {
138 static int shown; 139 static int shown;
139 140
140 - AUD_log (NULL, "Error a bug that was just triggered in %s\n", funcname); 141 + AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
141 if (!shown) { 142 if (!shown) {
142 shown = 1; 143 shown = 1;
143 AUD_log (NULL, "Save all your work and restart without audio\n"); 144 AUD_log (NULL, "Save all your work and restart without audio\n");
@@ -621,6 +622,121 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) @@ -621,6 +622,121 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
621 } 622 }
622 623
623 /* 624 /*
  625 + * Capture
  626 + */
  627 +static void noop_conv (st_sample_t *dst, const void *src,
  628 + int samples, volume_t *vol)
  629 +{
  630 + (void) src;
  631 + (void) dst;
  632 + (void) samples;
  633 + (void) vol;
  634 +}
  635 +
  636 +static CaptureVoiceOut *audio_pcm_capture_find_specific (
  637 + AudioState *s,
  638 + audsettings_t *as,
  639 + int endian
  640 + )
  641 +{
  642 + CaptureVoiceOut *cap;
  643 + int swap_endian = audio_need_to_swap_endian (endian);
  644 +
  645 + for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
  646 + if ((cap->hw.info.swap_endian == swap_endian)
  647 + && audio_pcm_info_eq (&cap->hw.info, as)) {
  648 + return cap;
  649 + }
  650 + }
  651 + return NULL;
  652 +}
  653 +
  654 +static void audio_notify_capture (CaptureVoiceOut *cap, int enabled)
  655 +{
  656 + if (cap->hw.enabled != enabled) {
  657 + struct capture_callback *cb;
  658 +
  659 + cap->hw.enabled = enabled;
  660 + for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
  661 + cb->ops.state (cb->opaque, enabled);
  662 + }
  663 + }
  664 +}
  665 +
  666 +static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
  667 +{
  668 + HWVoiceOut *hw = &cap->hw;
  669 + SWVoiceOut *sw;
  670 + int enabled = 0;
  671 +
  672 + for (sw = hw->sw_cap_head.lh_first; sw; sw = sw->cap_entries.le_next) {
  673 + if (sw->active) {
  674 + enabled = 1;
  675 + break;
  676 + }
  677 + }
  678 + audio_notify_capture (cap, enabled);
  679 +}
  680 +
  681 +static void audio_detach_capture (HWVoiceOut *hw)
  682 +{
  683 + SWVoiceOut *sw;
  684 +
  685 + for (sw = hw->sw_cap_head.lh_first; sw; sw = sw->cap_entries.le_next) {
  686 + if (sw->rate) {
  687 + st_rate_stop (sw->rate);
  688 + sw->rate = NULL;
  689 + }
  690 +
  691 + LIST_REMOVE (sw, entries);
  692 + LIST_REMOVE (sw, cap_entries);
  693 + qemu_free (sw);
  694 + audio_recalc_and_notify_capture ((CaptureVoiceOut *) sw->hw);
  695 + }
  696 +}
  697 +
  698 +static int audio_attach_capture (AudioState *s, HWVoiceOut *hw)
  699 +{
  700 + CaptureVoiceOut *cap;
  701 +
  702 + audio_detach_capture (hw);
  703 + for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
  704 + SWVoiceOut *sw;
  705 + HWVoiceOut *hw_cap;
  706 +
  707 + hw_cap = &cap->hw;
  708 + sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
  709 + if (!sw) {
  710 + dolog ("Could not allocate soft capture voice (%zu bytes)\n",
  711 + sizeof (*sw));
  712 + return -1;
  713 + }
  714 +
  715 + sw->info = hw->info;
  716 + sw->hw = hw_cap;
  717 + sw->empty = 1;
  718 + sw->active = hw->enabled;
  719 + sw->conv = noop_conv;
  720 + sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
  721 + sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
  722 + if (!sw->rate) {
  723 + dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
  724 + qemu_free (sw);
  725 + return -1;
  726 + }
  727 + LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
  728 + LIST_INSERT_HEAD (&hw->sw_cap_head, sw, cap_entries);
  729 + if (sw->active) {
  730 + audio_notify_capture (cap, 1);
  731 + }
  732 + else {
  733 + audio_recalc_and_notify_capture (cap);
  734 + }
  735 + }
  736 + return 0;
  737 +}
  738 +
  739 +/*
624 * Hard voice (capture) 740 * Hard voice (capture)
625 */ 741 */
626 static int audio_pcm_hw_find_min_in (HWVoiceIn *hw) 742 static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
@@ -916,17 +1032,11 @@ void AUD_set_active_out (SWVoiceOut *sw, int on) @@ -916,17 +1032,11 @@ void AUD_set_active_out (SWVoiceOut *sw, int on)
916 SWVoiceOut *temp_sw; 1032 SWVoiceOut *temp_sw;
917 1033
918 if (on) { 1034 if (on) {
919 - int total;  
920 -  
921 hw->pending_disable = 0; 1035 hw->pending_disable = 0;
922 if (!hw->enabled) { 1036 if (!hw->enabled) {
923 hw->enabled = 1; 1037 hw->enabled = 1;
924 hw->pcm_ops->ctl_out (hw, VOICE_ENABLE); 1038 hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);
925 } 1039 }
926 -  
927 - if (sw->empty) {  
928 - total = 0;  
929 - }  
930 } 1040 }
931 else { 1041 else {
932 if (hw->enabled) { 1042 if (hw->enabled) {
@@ -940,6 +1050,13 @@ void AUD_set_active_out (SWVoiceOut *sw, int on) @@ -940,6 +1050,13 @@ void AUD_set_active_out (SWVoiceOut *sw, int on)
940 hw->pending_disable = nb_active == 1; 1050 hw->pending_disable = nb_active == 1;
941 } 1051 }
942 } 1052 }
  1053 + for (temp_sw = hw->sw_cap_head.lh_first; temp_sw;
  1054 + temp_sw = temp_sw->entries.le_next) {
  1055 + temp_sw->active = hw->enabled;
  1056 + if (hw->enabled) {
  1057 + audio_notify_capture ((CaptureVoiceOut *) temp_sw->hw, 1);
  1058 + }
  1059 + }
943 sw->active = on; 1060 sw->active = on;
944 } 1061 }
945 } 1062 }
@@ -1031,6 +1148,41 @@ static int audio_get_free (SWVoiceOut *sw) @@ -1031,6 +1148,41 @@ static int audio_get_free (SWVoiceOut *sw)
1031 return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift; 1148 return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
1032 } 1149 }
1033 1150
  1151 +static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
  1152 +{
  1153 + int n;
  1154 +
  1155 + if (hw->enabled) {
  1156 + SWVoiceOut *sw;
  1157 +
  1158 + for (sw = hw->sw_cap_head.lh_first; sw; sw = sw->cap_entries.le_next) {
  1159 + int rpos2 = rpos;
  1160 +
  1161 + n = samples;
  1162 + while (n) {
  1163 + int till_end_of_hw = hw->samples - rpos2;
  1164 + int to_write = audio_MIN (till_end_of_hw, n);
  1165 + int bytes = to_write << hw->info.shift;
  1166 + int written;
  1167 +
  1168 + sw->buf = hw->mix_buf + rpos2;
  1169 + written = audio_pcm_sw_write (sw, NULL, bytes);
  1170 + if (written - bytes) {
  1171 + dolog ("Could not mix %d bytes into a capture buffer",
  1172 + bytes);
  1173 + break;
  1174 + }
  1175 + n -= to_write;
  1176 + rpos2 = (rpos2 + to_write) % hw->samples;
  1177 + }
  1178 + }
  1179 + }
  1180 +
  1181 + n = audio_MIN (samples, hw->samples - rpos);
  1182 + mixeng_clear (hw->mix_buf + rpos, n);
  1183 + mixeng_clear (hw->mix_buf, samples - n);
  1184 +}
  1185 +
1034 static void audio_run_out (AudioState *s) 1186 static void audio_run_out (AudioState *s)
1035 { 1187 {
1036 HWVoiceOut *hw = NULL; 1188 HWVoiceOut *hw = NULL;
@@ -1038,7 +1190,7 @@ static void audio_run_out (AudioState *s) @@ -1038,7 +1190,7 @@ static void audio_run_out (AudioState *s)
1038 1190
1039 while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) { 1191 while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
1040 int played; 1192 int played;
1041 - int live, free, nb_live, cleanup_required; 1193 + int live, free, nb_live, cleanup_required, prev_rpos;
1042 1194
1043 live = audio_pcm_hw_get_live_out2 (hw, &nb_live); 1195 live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
1044 if (!nb_live) { 1196 if (!nb_live) {
@@ -1057,6 +1209,11 @@ static void audio_run_out (AudioState *s) @@ -1057,6 +1209,11 @@ static void audio_run_out (AudioState *s)
1057 hw->enabled = 0; 1209 hw->enabled = 0;
1058 hw->pending_disable = 0; 1210 hw->pending_disable = 0;
1059 hw->pcm_ops->ctl_out (hw, VOICE_DISABLE); 1211 hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
  1212 + for (sw = hw->sw_cap_head.lh_first; sw;
  1213 + sw = sw->cap_entries.le_next) {
  1214 + sw->active = 0;
  1215 + audio_recalc_and_notify_capture ((CaptureVoiceOut *) sw->hw);
  1216 + }
1060 continue; 1217 continue;
1061 } 1218 }
1062 1219
@@ -1072,6 +1229,7 @@ static void audio_run_out (AudioState *s) @@ -1072,6 +1229,7 @@ static void audio_run_out (AudioState *s)
1072 continue; 1229 continue;
1073 } 1230 }
1074 1231
  1232 + prev_rpos = hw->rpos;
1075 played = hw->pcm_ops->run_out (hw); 1233 played = hw->pcm_ops->run_out (hw);
1076 if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) { 1234 if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
1077 dolog ("hw->rpos=%d hw->samples=%d played=%d\n", 1235 dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
@@ -1085,6 +1243,7 @@ static void audio_run_out (AudioState *s) @@ -1085,6 +1243,7 @@ static void audio_run_out (AudioState *s)
1085 1243
1086 if (played) { 1244 if (played) {
1087 hw->ts_helper += played; 1245 hw->ts_helper += played;
  1246 + audio_capture_mix_and_clear (hw, prev_rpos, played);
1088 } 1247 }
1089 1248
1090 cleanup_required = 0; 1249 cleanup_required = 0;
@@ -1158,12 +1317,60 @@ static void audio_run_in (AudioState *s) @@ -1158,12 +1317,60 @@ static void audio_run_in (AudioState *s)
1158 } 1317 }
1159 } 1318 }
1160 1319
  1320 +static void audio_run_capture (AudioState *s)
  1321 +{
  1322 + CaptureVoiceOut *cap;
  1323 +
  1324 + for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
  1325 + int live, rpos, captured;
  1326 + HWVoiceOut *hw = &cap->hw;
  1327 + SWVoiceOut *sw;
  1328 +
  1329 + captured = live = audio_pcm_hw_get_live_out (hw);
  1330 + rpos = hw->rpos;
  1331 + while (live) {
  1332 + int left = hw->samples - rpos;
  1333 + int to_capture = audio_MIN (live, left);
  1334 + st_sample_t *src;
  1335 + struct capture_callback *cb;
  1336 +
  1337 + src = hw->mix_buf + rpos;
  1338 + hw->clip (cap->buf, src, to_capture);
  1339 + mixeng_clear (src, to_capture);
  1340 +
  1341 + for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
  1342 + cb->ops.capture (cb->opaque, cap->buf,
  1343 + to_capture << hw->info.shift);
  1344 + }
  1345 + rpos = (rpos + to_capture) % hw->samples;
  1346 + live -= to_capture;
  1347 + }
  1348 + hw->rpos = rpos;
  1349 +
  1350 + for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
  1351 + if (!sw->active && sw->empty) {
  1352 + continue;
  1353 + }
  1354 +
  1355 + if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
  1356 + dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
  1357 + captured, sw->total_hw_samples_mixed);
  1358 + captured = sw->total_hw_samples_mixed;
  1359 + }
  1360 +
  1361 + sw->total_hw_samples_mixed -= captured;
  1362 + sw->empty = sw->total_hw_samples_mixed == 0;
  1363 + }
  1364 + }
  1365 +}
  1366 +
1161 static void audio_timer (void *opaque) 1367 static void audio_timer (void *opaque)
1162 { 1368 {
1163 AudioState *s = opaque; 1369 AudioState *s = opaque;
1164 1370
1165 audio_run_out (s); 1371 audio_run_out (s);
1166 audio_run_in (s); 1372 audio_run_in (s);
  1373 + audio_run_capture (s);
1167 1374
1168 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks); 1375 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
1169 } 1376 }
@@ -1327,8 +1534,14 @@ static void audio_atexit (void) @@ -1327,8 +1534,14 @@ static void audio_atexit (void)
1327 HWVoiceIn *hwi = NULL; 1534 HWVoiceIn *hwi = NULL;
1328 1535
1329 while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) { 1536 while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
  1537 + SWVoiceOut *sw;
  1538 +
1330 hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE); 1539 hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
1331 hwo->pcm_ops->fini_out (hwo); 1540 hwo->pcm_ops->fini_out (hwo);
  1541 +
  1542 + for (sw = hwo->sw_cap_head.lh_first; sw; sw = sw->entries.le_next) {
  1543 + audio_notify_capture ((CaptureVoiceOut *) sw->hw, 0);
  1544 + }
1332 } 1545 }
1333 1546
1334 while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) { 1547 while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
@@ -1383,6 +1596,7 @@ AudioState *AUD_init (void) @@ -1383,6 +1596,7 @@ AudioState *AUD_init (void)
1383 1596
1384 LIST_INIT (&s->hw_head_out); 1597 LIST_INIT (&s->hw_head_out);
1385 LIST_INIT (&s->hw_head_in); 1598 LIST_INIT (&s->hw_head_in);
  1599 + LIST_INIT (&s->cap_head);
1386 atexit (audio_atexit); 1600 atexit (audio_atexit);
1387 1601
1388 s->ts = qemu_new_timer (vm_clock, audio_timer, s); 1602 s->ts = qemu_new_timer (vm_clock, audio_timer, s);
@@ -1479,3 +1693,100 @@ AudioState *AUD_init (void) @@ -1479,3 +1693,100 @@ AudioState *AUD_init (void)
1479 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks); 1693 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
1480 return s; 1694 return s;
1481 } 1695 }
  1696 +
  1697 +int AUD_add_capture (
  1698 + AudioState *s,
  1699 + audsettings_t *as,
  1700 + int endian,
  1701 + struct audio_capture_ops *ops,
  1702 + void *cb_opaque
  1703 + )
  1704 +{
  1705 + CaptureVoiceOut *cap;
  1706 + struct capture_callback *cb;
  1707 +
  1708 + if (!s) {
  1709 + /* XXX suppress */
  1710 + s = &glob_audio_state;
  1711 + }
  1712 +
  1713 + if (audio_validate_settigs (as)) {
  1714 + dolog ("Invalid settings were passed when trying to add capture\n");
  1715 + audio_print_settings (as);
  1716 + return -1;
  1717 + }
  1718 +
  1719 + cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
  1720 + if (!cb) {
  1721 + dolog ("Could not allocate capture callback information, size %zu\n",
  1722 + sizeof (*cb));
  1723 + goto err0;
  1724 + }
  1725 + cb->ops = *ops;
  1726 + cb->opaque = cb_opaque;
  1727 +
  1728 + cap = audio_pcm_capture_find_specific (s, as, endian);
  1729 + if (cap) {
  1730 + LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
  1731 + return 0;
  1732 + }
  1733 + else {
  1734 + HWVoiceOut *hw;
  1735 + CaptureVoiceOut *cap;
  1736 +
  1737 + cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
  1738 + if (!cap) {
  1739 + dolog ("Could not allocate capture voice, size %zu\n",
  1740 + sizeof (*cap));
  1741 + goto err1;
  1742 + }
  1743 +
  1744 + hw = &cap->hw;
  1745 + LIST_INIT (&hw->sw_head);
  1746 + LIST_INIT (&cap->cb_head);
  1747 +
  1748 + /* XXX find a more elegant way */
  1749 + hw->samples = 4096 * 4;
  1750 + hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
  1751 + sizeof (st_sample_t));
  1752 + if (!hw->mix_buf) {
  1753 + dolog ("Could not allocate capture mix buffer (%d samples)\n",
  1754 + hw->samples);
  1755 + goto err2;
  1756 + }
  1757 +
  1758 + audio_pcm_init_info (&hw->info, as, endian);
  1759 +
  1760 + cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
  1761 + if (!cap->buf) {
  1762 + dolog ("Could not allocate capture buffer "
  1763 + "(%d samples, each %d bytes)\n",
  1764 + hw->samples, 1 << hw->info.shift);
  1765 + goto err3;
  1766 + }
  1767 +
  1768 + hw->clip = mixeng_clip
  1769 + [hw->info.nchannels == 2]
  1770 + [hw->info.sign]
  1771 + [hw->info.swap_endian]
  1772 + [hw->info.bits == 16];
  1773 +
  1774 + LIST_INSERT_HEAD (&s->cap_head, cap, entries);
  1775 + LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
  1776 +
  1777 + hw = NULL;
  1778 + while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
  1779 + audio_attach_capture (s, hw);
  1780 + }
  1781 + return 0;
  1782 +
  1783 + err3:
  1784 + qemu_free (cap->hw.mix_buf);
  1785 + err2:
  1786 + qemu_free (cap);
  1787 + err1:
  1788 + qemu_free (cb);
  1789 + err0:
  1790 + return -1;
  1791 + }
  1792 +}
audio/audio.h
@@ -41,6 +41,11 @@ typedef struct { @@ -41,6 +41,11 @@ typedef struct {
41 audfmt_e fmt; 41 audfmt_e fmt;
42 } audsettings_t; 42 } audsettings_t;
43 43
  44 +struct audio_capture_ops {
  45 + void (*state) (void *opaque, int enabled);
  46 + void (*capture) (void *opaque, void *buf, int size);
  47 +};
  48 +
44 typedef struct AudioState AudioState; 49 typedef struct AudioState AudioState;
45 typedef struct SWVoiceOut SWVoiceOut; 50 typedef struct SWVoiceOut SWVoiceOut;
46 typedef struct SWVoiceIn SWVoiceIn; 51 typedef struct SWVoiceIn SWVoiceIn;
@@ -66,6 +71,13 @@ AudioState *AUD_init (void); @@ -66,6 +71,13 @@ AudioState *AUD_init (void);
66 void AUD_help (void); 71 void AUD_help (void);
67 void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card); 72 void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card);
68 void AUD_remove_card (QEMUSoundCard *card); 73 void AUD_remove_card (QEMUSoundCard *card);
  74 +int AUD_add_capture (
  75 + AudioState *s,
  76 + audsettings_t *as,
  77 + int endian,
  78 + struct audio_capture_ops *ops,
  79 + void *opaque
  80 + );
69 81
70 SWVoiceOut *AUD_open_out ( 82 SWVoiceOut *AUD_open_out (
71 QEMUSoundCard *card, 83 QEMUSoundCard *card,
@@ -111,7 +123,7 @@ static inline void *advance (void *p, int incr) @@ -111,7 +123,7 @@ static inline void *advance (void *p, int incr)
111 } 123 }
112 124
113 uint32_t popcount (uint32_t u); 125 uint32_t popcount (uint32_t u);
114 -inline uint32_t lsbindex (uint32_t u); 126 +uint32_t lsbindex (uint32_t u);
115 127
116 #ifdef __GNUC__ 128 #ifdef __GNUC__
117 #define audio_MIN(a, b) ( __extension__ ({ \ 129 #define audio_MIN(a, b) ( __extension__ ({ \
audio/audio_int.h
@@ -79,6 +79,7 @@ typedef struct HWVoiceOut { @@ -79,6 +79,7 @@ typedef struct HWVoiceOut {
79 79
80 int samples; 80 int samples;
81 LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; 81 LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
  82 + LIST_HEAD (sw_cap_listhead, SWVoiceOut) sw_cap_head;
82 struct audio_pcm_ops *pcm_ops; 83 struct audio_pcm_ops *pcm_ops;
83 LIST_ENTRY (HWVoiceOut) entries; 84 LIST_ENTRY (HWVoiceOut) entries;
84 } HWVoiceOut; 85 } HWVoiceOut;
@@ -115,6 +116,7 @@ struct SWVoiceOut { @@ -115,6 +116,7 @@ struct SWVoiceOut {
115 volume_t vol; 116 volume_t vol;
116 struct audio_callback callback; 117 struct audio_callback callback;
117 LIST_ENTRY (SWVoiceOut) entries; 118 LIST_ENTRY (SWVoiceOut) entries;
  119 + LIST_ENTRY (SWVoiceOut) cap_entries;
118 }; 120 };
119 121
120 struct SWVoiceIn { 122 struct SWVoiceIn {
@@ -160,14 +162,28 @@ struct audio_pcm_ops { @@ -160,14 +162,28 @@ struct audio_pcm_ops {
160 int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); 162 int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
161 }; 163 };
162 164
  165 +struct capture_callback {
  166 + struct audio_capture_ops ops;
  167 + void *opaque;
  168 + LIST_ENTRY (capture_callback) entries;
  169 +};
  170 +
  171 +typedef struct CaptureVoiceOut {
  172 + HWVoiceOut hw;
  173 + void *buf;
  174 + LIST_HEAD (cb_listhead, capture_callback) cb_head;
  175 + LIST_ENTRY (CaptureVoiceOut) entries;
  176 +} CaptureVoiceOut;
  177 +
163 struct AudioState { 178 struct AudioState {
164 struct audio_driver *drv; 179 struct audio_driver *drv;
165 void *drv_opaque; 180 void *drv_opaque;
166 181
167 QEMUTimer *ts; 182 QEMUTimer *ts;
168 - LIST_HEAD (card_head, QEMUSoundCard) card_head; 183 + LIST_HEAD (card_listhead, QEMUSoundCard) card_head;
169 LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in; 184 LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
170 LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out; 185 LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
  186 + LIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
171 int nb_hw_voices_out; 187 int nb_hw_voices_out;
172 int nb_hw_voices_in; 188 int nb_hw_voices_in;
173 }; 189 };
audio/audio_template.h
@@ -200,6 +200,9 @@ static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp) @@ -200,6 +200,9 @@ static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
200 HW *hw = *hwp; 200 HW *hw = *hwp;
201 201
202 if (!hw->sw_head.lh_first) { 202 if (!hw->sw_head.lh_first) {
  203 +#ifdef DAC
  204 + audio_detach_capture (hw);
  205 +#endif
203 LIST_REMOVE (hw, entries); 206 LIST_REMOVE (hw, entries);
204 glue (s->nb_hw_voices_, TYPE) += 1; 207 glue (s->nb_hw_voices_, TYPE) += 1;
205 glue (audio_pcm_hw_free_resources_ ,TYPE) (hw); 208 glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
@@ -266,7 +269,9 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as) @@ -266,7 +269,9 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
266 269
267 hw->pcm_ops = drv->pcm_ops; 270 hw->pcm_ops = drv->pcm_ops;
268 LIST_INIT (&hw->sw_head); 271 LIST_INIT (&hw->sw_head);
269 - 272 +#ifdef DAC
  273 + LIST_INIT (&hw->sw_cap_head);
  274 +#endif
270 if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) { 275 if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
271 goto err0; 276 goto err0;
272 } 277 }
@@ -292,6 +297,9 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as) @@ -292,6 +297,9 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
292 297
293 LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries); 298 LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
294 glue (s->nb_hw_voices_, TYPE) -= 1; 299 glue (s->nb_hw_voices_, TYPE) -= 1;
  300 +#ifdef DAC
  301 + audio_attach_capture (s, hw);
  302 +#endif
295 return hw; 303 return hw;
296 304
297 err1: 305 err1:
@@ -542,7 +550,7 @@ uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts) @@ -542,7 +550,7 @@ uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
542 550
543 cur_ts = sw->hw->ts_helper; 551 cur_ts = sw->hw->ts_helper;
544 old_ts = ts->old_ts; 552 old_ts = ts->old_ts;
545 - /* dolog ("cur %" PRId64 " old %" PRId64 "\n", cur_ts, old_ts); */ 553 + /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
546 554
547 if (cur_ts >= old_ts) { 555 if (cur_ts >= old_ts) {
548 delta = cur_ts - old_ts; 556 delta = cur_ts - old_ts;
audio/coreaudio.c
@@ -275,8 +275,6 @@ static OSStatus audioDeviceIOProc( @@ -275,8 +275,6 @@ static OSStatus audioDeviceIOProc(
275 #endif 275 #endif
276 } 276 }
277 277
278 - /* cleanup */  
279 - mixeng_clear (src, frameCount);  
280 rpos = (rpos + frameCount) % hw->samples; 278 rpos = (rpos + frameCount) % hw->samples;
281 core->decr += frameCount; 279 core->decr += frameCount;
282 core->rpos = rpos; 280 core->rpos = rpos;
audio/dsound_template.h
@@ -70,7 +70,13 @@ static int glue (dsound_lock_, TYPE) ( @@ -70,7 +70,13 @@ static int glue (dsound_lock_, TYPE) (
70 int i; 70 int i;
71 LPVOID p1 = NULL, p2 = NULL; 71 LPVOID p1 = NULL, p2 = NULL;
72 DWORD blen1 = 0, blen2 = 0; 72 DWORD blen1 = 0, blen2 = 0;
  73 + DWORD flag;
73 74
  75 +#ifdef DSBTYPE_IN
  76 + flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
  77 +#else
  78 + flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
  79 +#endif
74 for (i = 0; i < conf.lock_retries; ++i) { 80 for (i = 0; i < conf.lock_retries; ++i) {
75 hr = glue (IFACE, _Lock) ( 81 hr = glue (IFACE, _Lock) (
76 buf, 82 buf,
@@ -80,13 +86,7 @@ static int glue (dsound_lock_, TYPE) ( @@ -80,13 +86,7 @@ static int glue (dsound_lock_, TYPE) (
80 &blen1, 86 &blen1,
81 &p2, 87 &p2,
82 &blen2, 88 &blen2,
83 - (entire  
84 -#ifdef DSBTYPE_IN  
85 - ? DSCBLOCK_ENTIREBUFFER  
86 -#else  
87 - ? DSBLOCK_ENTIREBUFFER  
88 -#endif  
89 - : 0) 89 + flag
90 ); 90 );
91 91
92 if (FAILED (hr)) { 92 if (FAILED (hr)) {
audio/dsoundaudio.c
@@ -453,13 +453,11 @@ static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len) @@ -453,13 +453,11 @@ static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
453 453
454 if (src_len1) { 454 if (src_len1) {
455 hw->clip (dst, src1, src_len1); 455 hw->clip (dst, src1, src_len1);
456 - mixeng_clear (src1, src_len1);  
457 } 456 }
458 457
459 if (src_len2) { 458 if (src_len2) {
460 dst = advance (dst, src_len1 << hw->info.shift); 459 dst = advance (dst, src_len1 << hw->info.shift);
461 hw->clip (dst, src2, src_len2); 460 hw->clip (dst, src2, src_len2);
462 - mixeng_clear (src2, src_len2);  
463 } 461 }
464 462
465 hw->rpos = pos % hw->samples; 463 hw->rpos = pos % hw->samples;
@@ -987,6 +985,12 @@ static void *dsound_audio_init (void) @@ -987,6 +985,12 @@ static void *dsound_audio_init (void)
987 hr = IDirectSound_Initialize (s->dsound, NULL); 985 hr = IDirectSound_Initialize (s->dsound, NULL);
988 if (FAILED (hr)) { 986 if (FAILED (hr)) {
989 dsound_logerr (hr, "Could not initialize DirectSound\n"); 987 dsound_logerr (hr, "Could not initialize DirectSound\n");
  988 +
  989 + hr = IDirectSound_Release (s->dsound);
  990 + if (FAILED (hr)) {
  991 + dsound_logerr (hr, "Could not release DirectSound\n");
  992 + }
  993 + s->dsound = NULL;
990 return NULL; 994 return NULL;
991 } 995 }
992 996
audio/fmodaudio.c
@@ -153,13 +153,11 @@ static void fmod_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len) @@ -153,13 +153,11 @@ static void fmod_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
153 153
154 if (src_len1) { 154 if (src_len1) {
155 hw->clip (dst, src1, src_len1); 155 hw->clip (dst, src1, src_len1);
156 - mixeng_clear (src1, src_len1);  
157 } 156 }
158 157
159 if (src_len2) { 158 if (src_len2) {
160 dst = advance (dst, src_len1 << hw->info.shift); 159 dst = advance (dst, src_len1 << hw->info.shift);
161 hw->clip (dst, src2, src_len2); 160 hw->clip (dst, src2, src_len2);
162 - mixeng_clear (src2, src_len2);  
163 } 161 }
164 162
165 hw->rpos = pos % hw->samples; 163 hw->rpos = pos % hw->samples;
audio/noaudio.c
@@ -40,22 +40,21 @@ static int no_run_out (HWVoiceOut *hw) @@ -40,22 +40,21 @@ static int no_run_out (HWVoiceOut *hw)
40 { 40 {
41 NoVoiceOut *no = (NoVoiceOut *) hw; 41 NoVoiceOut *no = (NoVoiceOut *) hw;
42 int live, decr, samples; 42 int live, decr, samples;
43 - int64_t now = qemu_get_clock (vm_clock);  
44 - int64_t ticks = now - no->old_ticks;  
45 - int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;  
46 -  
47 - if (bytes > INT_MAX) {  
48 - samples = INT_MAX >> hw->info.shift;  
49 - }  
50 - else {  
51 - samples = bytes >> hw->info.shift;  
52 - } 43 + int64_t now;
  44 + int64_t ticks;
  45 + int64_t bytes;
53 46
54 live = audio_pcm_hw_get_live_out (&no->hw); 47 live = audio_pcm_hw_get_live_out (&no->hw);
55 if (!live) { 48 if (!live) {
56 return 0; 49 return 0;
57 } 50 }
58 51
  52 + now = qemu_get_clock (vm_clock);
  53 + ticks = now - no->old_ticks;
  54 + bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
  55 + bytes = audio_MIN (bytes, INT_MAX);
  56 + samples = bytes >> hw->info.shift;
  57 +
59 no->old_ticks = now; 58 no->old_ticks = now;
60 decr = audio_MIN (live, samples); 59 decr = audio_MIN (live, samples);
61 hw->rpos = (hw->rpos + decr) % hw->samples; 60 hw->rpos = (hw->rpos + decr) % hw->samples;
@@ -101,17 +100,20 @@ static void no_fini_in (HWVoiceIn *hw) @@ -101,17 +100,20 @@ static void no_fini_in (HWVoiceIn *hw)
101 static int no_run_in (HWVoiceIn *hw) 100 static int no_run_in (HWVoiceIn *hw)
102 { 101 {
103 NoVoiceIn *no = (NoVoiceIn *) hw; 102 NoVoiceIn *no = (NoVoiceIn *) hw;
104 - int64_t now = qemu_get_clock (vm_clock);  
105 - int64_t ticks = now - no->old_ticks;  
106 - int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;  
107 int live = audio_pcm_hw_get_live_in (hw); 103 int live = audio_pcm_hw_get_live_in (hw);
108 int dead = hw->samples - live; 104 int dead = hw->samples - live;
109 int samples; 105 int samples;
110 106
111 - bytes = audio_MIN (bytes, INT_MAX);  
112 - samples = bytes >> hw->info.shift;  
113 - samples = audio_MIN (samples, dead); 107 + if (dead) {
  108 + int64_t now = qemu_get_clock (vm_clock);
  109 + int64_t ticks = now - no->old_ticks;
  110 + int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
114 111
  112 + no->old_ticks = now;
  113 + bytes = audio_MIN (bytes, INT_MAX);
  114 + samples = bytes >> hw->info.shift;
  115 + samples = audio_MIN (samples, dead);
  116 + }
115 return samples; 117 return samples;
116 } 118 }
117 119
audio/ossaudio.c
@@ -55,12 +55,14 @@ static struct { @@ -55,12 +55,14 @@ static struct {
55 int fragsize; 55 int fragsize;
56 const char *devpath_out; 56 const char *devpath_out;
57 const char *devpath_in; 57 const char *devpath_in;
  58 + int debug;
58 } conf = { 59 } conf = {
59 .try_mmap = 0, 60 .try_mmap = 0,
60 .nfrags = 4, 61 .nfrags = 4,
61 .fragsize = 4096, 62 .fragsize = 4096,
62 .devpath_out = "/dev/dsp", 63 .devpath_out = "/dev/dsp",
63 - .devpath_in = "/dev/dsp" 64 + .devpath_in = "/dev/dsp",
  65 + .debug = 0
64 }; 66 };
65 67
66 struct oss_params { 68 struct oss_params {
@@ -324,9 +326,20 @@ static int oss_run_out (HWVoiceOut *hw) @@ -324,9 +326,20 @@ static int oss_run_out (HWVoiceOut *hw)
324 return 0; 326 return 0;
325 } 327 }
326 328
327 - if (abinfo.bytes < 0 || abinfo.bytes > bufsize) {  
328 - ldebug ("warning: Invalid available size, size=%d bufsize=%d\n",  
329 - abinfo.bytes, bufsize); 329 + if (abinfo.bytes > bufsize) {
  330 + if (conf.debug) {
  331 + dolog ("warning: Invalid available size, size=%d bufsize=%d\n"
  332 + "please report your OS/audio hw to malc@pulsesoft.com\n",
  333 + abinfo.bytes, bufsize);
  334 + }
  335 + abinfo.bytes = bufsize;
  336 + }
  337 +
  338 + if (abinfo.bytes < 0) {
  339 + if (conf.debug) {
  340 + dolog ("warning: Invalid available size, size=%d bufsize=%d\n",
  341 + abinfo.bytes, bufsize);
  342 + }
330 return 0; 343 return 0;
331 } 344 }
332 345
@@ -369,15 +382,12 @@ static int oss_run_out (HWVoiceOut *hw) @@ -369,15 +382,12 @@ static int oss_run_out (HWVoiceOut *hw)
369 "alignment %d\n", 382 "alignment %d\n",
370 wbytes, written, hw->info.align + 1); 383 wbytes, written, hw->info.align + 1);
371 } 384 }
372 - mixeng_clear (src, wsamples);  
373 decr -= wsamples; 385 decr -= wsamples;
374 rpos = (rpos + wsamples) % hw->samples; 386 rpos = (rpos + wsamples) % hw->samples;
375 break; 387 break;
376 } 388 }
377 } 389 }
378 390
379 - mixeng_clear (src, convert_samples);  
380 -  
381 rpos = (rpos + convert_samples) % hw->samples; 391 rpos = (rpos + convert_samples) % hw->samples;
382 samples -= convert_samples; 392 samples -= convert_samples;
383 } 393 }
@@ -730,6 +740,8 @@ static struct audio_option oss_options[] = { @@ -730,6 +740,8 @@ static struct audio_option oss_options[] = {
730 "Path to DAC device", NULL, 0}, 740 "Path to DAC device", NULL, 0},
731 {"ADC_DEV", AUD_OPT_STR, &conf.devpath_in, 741 {"ADC_DEV", AUD_OPT_STR, &conf.devpath_in,
732 "Path to ADC device", NULL, 0}, 742 "Path to ADC device", NULL, 0},
  743 + {"DEBUG", AUD_OPT_BOOL, &conf.debug,
  744 + "Turn on some debugging messages", NULL, 0},
733 {NULL, 0, NULL, NULL, NULL, 0} 745 {NULL, 0, NULL, NULL, NULL, 0}
734 }; 746 };
735 747
audio/sdlaudio.c
@@ -240,7 +240,6 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) @@ -240,7 +240,6 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
240 240
241 /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */ 241 /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
242 hw->clip (buf, src, chunk); 242 hw->clip (buf, src, chunk);
243 - mixeng_clear (src, chunk);  
244 sdl->rpos = (sdl->rpos + chunk) % hw->samples; 243 sdl->rpos = (sdl->rpos + chunk) % hw->samples;
245 to_mix -= chunk; 244 to_mix -= chunk;
246 buf += chunk << hw->info.shift; 245 buf += chunk << hw->info.shift;
audio/wavaudio.c
@@ -81,7 +81,6 @@ static int wav_run_out (HWVoiceOut *hw) @@ -81,7 +81,6 @@ static int wav_run_out (HWVoiceOut *hw)
81 81
82 hw->clip (dst, src, convert_samples); 82 hw->clip (dst, src, convert_samples);
83 qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift); 83 qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift);
84 - mixeng_clear (src, convert_samples);  
85 84
86 rpos = (rpos + convert_samples) % hw->samples; 85 rpos = (rpos + convert_samples) % hw->samples;
87 samples -= convert_samples; 86 samples -= convert_samples;
audio/wavcapture.c 0 โ†’ 100644
  1 +#include "vl.h"
  2 +
  3 +typedef struct {
  4 + QEMUFile *f;
  5 + int bytes;
  6 +} WAVState;
  7 +
  8 +/* VICE code: Store number as little endian. */
  9 +static void le_store (uint8_t *buf, uint32_t val, int len)
  10 +{
  11 + int i;
  12 + for (i = 0; i < len; i++) {
  13 + buf[i] = (uint8_t) (val & 0xff);
  14 + val >>= 8;
  15 + }
  16 +}
  17 +
  18 +static void wav_state_cb (void *opaque, int enabled)
  19 +{
  20 + WAVState *wav = opaque;
  21 +
  22 + if (!enabled) {
  23 + uint8_t rlen[4];
  24 + uint8_t dlen[4];
  25 + uint32_t datalen = wav->bytes;
  26 + uint32_t rifflen = datalen + 36;
  27 +
  28 + if (!wav->f) {
  29 + return;
  30 + }
  31 +
  32 + le_store (rlen, rifflen, 4);
  33 + le_store (dlen, datalen, 4);
  34 +
  35 + qemu_fseek (wav->f, 4, SEEK_SET);
  36 + qemu_put_buffer (wav->f, rlen, 4);
  37 +
  38 + qemu_fseek (wav->f, 32, SEEK_CUR);
  39 + qemu_put_buffer (wav->f, dlen, 4);
  40 + }
  41 + else {
  42 + qemu_fseek (wav->f, 0, SEEK_END);
  43 + }
  44 +}
  45 +
  46 +static void wav_capture_cb (void *opaque, void *buf, int size)
  47 +{
  48 + WAVState *wav = opaque;
  49 +
  50 + qemu_put_buffer (wav->f, buf, size);
  51 + wav->bytes += size;
  52 +}
  53 +
  54 +void wav_capture (const char *path, int freq, int bits16, int stereo)
  55 +{
  56 + WAVState *wav;
  57 + uint8_t hdr[] = {
  58 + 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
  59 + 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
  60 + 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
  61 + 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
  62 + };
  63 + audsettings_t as;
  64 + struct audio_capture_ops ops;
  65 + int shift;
  66 +
  67 + stereo = !!stereo;
  68 + bits16 = !!bits16;
  69 +
  70 + as.freq = freq;
  71 + as.nchannels = 1 << stereo;
  72 + as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
  73 +
  74 + ops.state = wav_state_cb;
  75 + ops.capture = wav_capture_cb;
  76 +
  77 + wav = qemu_mallocz (sizeof (*wav));
  78 + if (!wav) {
  79 + AUD_log ("wav", "Could not allocate memory (%zu bytes)", sizeof (*wav));
  80 + return;
  81 + }
  82 +
  83 + shift = bits16 + stereo;
  84 + hdr[34] = bits16 ? 0x10 : 0x08;
  85 +
  86 + le_store (hdr + 22, as.nchannels, 2);
  87 + le_store (hdr + 24, freq, 4);
  88 + le_store (hdr + 28, freq << shift, 4);
  89 + le_store (hdr + 32, 1 << shift, 2);
  90 +
  91 + wav->f = fopen (path, "wb");
  92 + if (!wav->f) {
  93 + AUD_log ("wav", "Failed to open wave file `%s'\nReason: %s\n",
  94 + path, strerror (errno));
  95 + qemu_free (wav);
  96 + return;
  97 + }
  98 +
  99 + qemu_put_buffer (wav->f, hdr, sizeof (hdr));
  100 + AUD_add_capture (NULL, &as, 0, &ops, wav);
  101 +}
hw/es1370.c
@@ -479,9 +479,10 @@ static inline uint32_t es1370_fixup (ES1370State *s, uint32_t addr) @@ -479,9 +479,10 @@ static inline uint32_t es1370_fixup (ES1370State *s, uint32_t addr)
479 IO_WRITE_PROTO (es1370_writeb) 479 IO_WRITE_PROTO (es1370_writeb)
480 { 480 {
481 ES1370State *s = opaque; 481 ES1370State *s = opaque;
482 - addr = es1370_fixup (s, addr);  
483 uint32_t shift, mask; 482 uint32_t shift, mask;
484 483
  484 + addr = es1370_fixup (s, addr);
  485 +
485 switch (addr) { 486 switch (addr) {
486 case ES1370_REG_CONTROL: 487 case ES1370_REG_CONTROL:
487 case ES1370_REG_CONTROL + 1: 488 case ES1370_REG_CONTROL + 1: