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
);
94 static void wav_capture_info (void *opaque
)
96 WAVState
*wav
= opaque
;
97 char *path
= wav
->path
;
99 monitor_printf (cur_mon
, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
100 wav
->freq
, wav
->bits
, wav
->nchannels
,
101 path
? path
: "<not available>", wav
->bytes
);
104 static struct capture_ops wav_capture_ops
= {
105 .destroy
= wav_capture_destroy
,
106 .info
= wav_capture_info
109 int wav_start_capture (CaptureState
*s
, const char *path
, int freq
,
110 int bits
, int nchannels
)
112 Monitor
*mon
= cur_mon
;
115 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
116 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
117 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
118 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
120 struct audsettings as
;
121 struct audio_capture_ops ops
;
122 int stereo
, bits16
, shift
;
123 CaptureVoiceOut
*cap
;
125 if (bits
!= 8 && bits
!= 16) {
126 monitor_printf (mon
, "incorrect bit count %d, must be 8 or 16\n", bits
);
130 if (nchannels
!= 1 && nchannels
!= 2) {
131 monitor_printf (mon
, "incorrect channel count %d, must be 1 or 2\n",
136 stereo
= nchannels
== 2;
140 as
.nchannels
= 1 << stereo
;
141 as
.fmt
= bits16
? AUD_FMT_S16
: AUD_FMT_U8
;
144 ops
.notify
= wav_notify
;
145 ops
.capture
= wav_capture
;
146 ops
.destroy
= wav_destroy
;
148 wav
= g_malloc0 (sizeof (*wav
));
150 shift
= bits16
+ stereo
;
151 hdr
[34] = bits16
? 0x10 : 0x08;
153 le_store (hdr
+ 22, as
.nchannels
, 2);
154 le_store (hdr
+ 24, freq
, 4);
155 le_store (hdr
+ 28, freq
<< shift
, 4);
156 le_store (hdr
+ 32, 1 << shift
, 2);
158 wav
->f
= fopen (path
, "wb");
160 monitor_printf (mon
, "Failed to open wave file `%s'\nReason: %s\n",
161 path
, strerror (errno
));
166 wav
->path
= g_strdup (path
);
168 wav
->nchannels
= nchannels
;
171 if (fwrite (hdr
, sizeof (hdr
), 1, wav
->f
) != 1) {
172 monitor_printf (mon
, "Failed to write header\nReason: %s\n",
177 cap
= AUD_add_capture (&as
, &ops
, wav
);
179 monitor_printf (mon
, "Failed to add audio capture\n");
185 s
->ops
= wav_capture_ops
;
190 if (fclose (wav
->f
)) {
191 monitor_printf (mon
, "Failed to close wave file\nReason: %s\n",