1 #include "qemu/osdep.h"
3 #include "monitor/monitor.h"
4 #include "qapi/error.h"
5 #include "qemu/error-report.h"
18 /* VICE code: Store number as little endian. */
19 static void le_store (uint8_t *buf
, uint32_t val
, int len
)
22 for (i
= 0; i
< len
; i
++) {
23 buf
[i
] = (uint8_t) (val
& 0xff);
28 static void wav_notify (void *opaque
, audcnotification_e cmd
)
34 static void wav_destroy (void *opaque
)
36 WAVState
*wav
= opaque
;
39 uint32_t datalen
= wav
->bytes
;
40 uint32_t rifflen
= datalen
+ 36;
41 Monitor
*mon
= cur_mon
;
44 le_store (rlen
, rifflen
, 4);
45 le_store (dlen
, datalen
, 4);
47 if (fseek (wav
->f
, 4, SEEK_SET
)) {
48 monitor_printf (mon
, "wav_destroy: rlen fseek failed\nReason: %s\n",
52 if (fwrite (rlen
, 4, 1, wav
->f
) != 1) {
53 monitor_printf (mon
, "wav_destroy: rlen fwrite failed\nReason %s\n",
57 if (fseek (wav
->f
, 32, SEEK_CUR
)) {
58 monitor_printf (mon
, "wav_destroy: dlen fseek failed\nReason %s\n",
62 if (fwrite (dlen
, 1, 4, wav
->f
) != 4) {
63 monitor_printf (mon
, "wav_destroy: dlen fwrite failed\nReason %s\n",
68 if (fclose (wav
->f
)) {
69 error_report("wav_destroy: fclose failed: %s", strerror(errno
));
76 static void wav_capture (void *opaque
, void *buf
, int size
)
78 WAVState
*wav
= opaque
;
80 if (fwrite (buf
, size
, 1, wav
->f
) != 1) {
81 monitor_printf (cur_mon
, "wav_capture: fwrite error\nReason: %s",
87 static void wav_capture_destroy (void *opaque
)
89 WAVState
*wav
= opaque
;
91 AUD_del_capture (wav
->cap
, wav
);
95 static void wav_capture_info (void *opaque
)
97 WAVState
*wav
= opaque
;
98 char *path
= wav
->path
;
100 monitor_printf (cur_mon
, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
101 wav
->freq
, wav
->bits
, wav
->nchannels
,
102 path
? path
: "<not available>", wav
->bytes
);
105 static struct capture_ops wav_capture_ops
= {
106 .destroy
= wav_capture_destroy
,
107 .info
= wav_capture_info
110 int wav_start_capture (CaptureState
*s
, const char *path
, int freq
,
111 int bits
, int nchannels
)
113 Monitor
*mon
= cur_mon
;
116 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
117 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
118 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
119 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
121 struct audsettings as
;
122 struct audio_capture_ops ops
;
123 int stereo
, bits16
, shift
;
124 CaptureVoiceOut
*cap
;
126 if (bits
!= 8 && bits
!= 16) {
127 monitor_printf (mon
, "incorrect bit count %d, must be 8 or 16\n", bits
);
131 if (nchannels
!= 1 && nchannels
!= 2) {
132 monitor_printf (mon
, "incorrect channel count %d, must be 1 or 2\n",
137 stereo
= nchannels
== 2;
141 as
.nchannels
= 1 << stereo
;
142 as
.fmt
= bits16
? AUD_FMT_S16
: AUD_FMT_U8
;
145 ops
.notify
= wav_notify
;
146 ops
.capture
= wav_capture
;
147 ops
.destroy
= wav_destroy
;
149 wav
= g_malloc0 (sizeof (*wav
));
151 shift
= bits16
+ stereo
;
152 hdr
[34] = bits16
? 0x10 : 0x08;
154 le_store (hdr
+ 22, as
.nchannels
, 2);
155 le_store (hdr
+ 24, freq
, 4);
156 le_store (hdr
+ 28, freq
<< shift
, 4);
157 le_store (hdr
+ 32, 1 << shift
, 2);
159 wav
->f
= fopen (path
, "wb");
161 monitor_printf (mon
, "Failed to open wave file `%s'\nReason: %s\n",
162 path
, strerror (errno
));
167 wav
->path
= g_strdup (path
);
169 wav
->nchannels
= nchannels
;
172 if (fwrite (hdr
, sizeof (hdr
), 1, wav
->f
) != 1) {
173 monitor_printf (mon
, "Failed to write header\nReason: %s\n",
178 cap
= AUD_add_capture (&as
, &ops
, wav
);
180 monitor_printf (mon
, "Failed to add audio capture\n");
186 s
->ops
= wav_capture_ops
;
191 if (fclose (wav
->f
)) {
192 monitor_printf (mon
, "Failed to close wave file\nReason: %s\n",