1 #include "qemu/osdep.h"
3 #include "monitor/monitor.h"
4 #include "qemu/error-report.h"
17 /* VICE code: Store number as little endian. */
18 static void le_store (uint8_t *buf
, uint32_t val
, int len
)
21 for (i
= 0; i
< len
; i
++) {
22 buf
[i
] = (uint8_t) (val
& 0xff);
27 static void wav_notify (void *opaque
, audcnotification_e cmd
)
33 static void wav_destroy (void *opaque
)
35 WAVState
*wav
= opaque
;
38 uint32_t datalen
= wav
->bytes
;
39 uint32_t rifflen
= datalen
+ 36;
40 Monitor
*mon
= cur_mon
;
43 le_store (rlen
, rifflen
, 4);
44 le_store (dlen
, datalen
, 4);
46 if (fseek (wav
->f
, 4, SEEK_SET
)) {
47 monitor_printf (mon
, "wav_destroy: rlen fseek failed\nReason: %s\n",
51 if (fwrite (rlen
, 4, 1, wav
->f
) != 1) {
52 monitor_printf (mon
, "wav_destroy: rlen fwrite failed\nReason %s\n",
56 if (fseek (wav
->f
, 32, SEEK_CUR
)) {
57 monitor_printf (mon
, "wav_destroy: dlen fseek failed\nReason %s\n",
61 if (fwrite (dlen
, 1, 4, wav
->f
) != 4) {
62 monitor_printf (mon
, "wav_destroy: dlen fwrite failed\nReason %s\n",
67 if (fclose (wav
->f
)) {
68 error_report("wav_destroy: fclose failed: %s", strerror(errno
));
75 static void wav_capture (void *opaque
, void *buf
, int size
)
77 WAVState
*wav
= opaque
;
79 if (fwrite (buf
, size
, 1, wav
->f
) != 1) {
80 monitor_printf (cur_mon
, "wav_capture: fwrite error\nReason: %s",
86 static void wav_capture_destroy (void *opaque
)
88 WAVState
*wav
= opaque
;
90 AUD_del_capture (wav
->cap
, wav
);
93 static void wav_capture_info (void *opaque
)
95 WAVState
*wav
= opaque
;
96 char *path
= wav
->path
;
98 monitor_printf (cur_mon
, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
99 wav
->freq
, wav
->bits
, wav
->nchannels
,
100 path
? path
: "<not available>", wav
->bytes
);
103 static struct capture_ops wav_capture_ops
= {
104 .destroy
= wav_capture_destroy
,
105 .info
= wav_capture_info
108 int wav_start_capture (CaptureState
*s
, const char *path
, int freq
,
109 int bits
, int nchannels
)
111 Monitor
*mon
= cur_mon
;
114 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
115 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
116 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
117 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
119 struct audsettings as
;
120 struct audio_capture_ops ops
;
121 int stereo
, bits16
, shift
;
122 CaptureVoiceOut
*cap
;
124 if (bits
!= 8 && bits
!= 16) {
125 monitor_printf (mon
, "incorrect bit count %d, must be 8 or 16\n", bits
);
129 if (nchannels
!= 1 && nchannels
!= 2) {
130 monitor_printf (mon
, "incorrect channel count %d, must be 1 or 2\n",
135 stereo
= nchannels
== 2;
139 as
.nchannels
= 1 << stereo
;
140 as
.fmt
= bits16
? AUD_FMT_S16
: AUD_FMT_U8
;
143 ops
.notify
= wav_notify
;
144 ops
.capture
= wav_capture
;
145 ops
.destroy
= wav_destroy
;
147 wav
= g_malloc0 (sizeof (*wav
));
149 shift
= bits16
+ stereo
;
150 hdr
[34] = bits16
? 0x10 : 0x08;
152 le_store (hdr
+ 22, as
.nchannels
, 2);
153 le_store (hdr
+ 24, freq
, 4);
154 le_store (hdr
+ 28, freq
<< shift
, 4);
155 le_store (hdr
+ 32, 1 << shift
, 2);
157 wav
->f
= fopen (path
, "wb");
159 monitor_printf (mon
, "Failed to open wave file `%s'\nReason: %s\n",
160 path
, strerror (errno
));
165 wav
->path
= g_strdup (path
);
167 wav
->nchannels
= nchannels
;
170 if (fwrite (hdr
, sizeof (hdr
), 1, wav
->f
) != 1) {
171 monitor_printf (mon
, "Failed to write header\nReason: %s\n",
176 cap
= AUD_add_capture (&as
, &ops
, wav
);
178 monitor_printf (mon
, "Failed to add audio capture\n");
184 s
->ops
= wav_capture_ops
;
189 if (fclose (wav
->f
)) {
190 monitor_printf (mon
, "Failed to close wave file\nReason: %s\n",