2 #include "monitor/monitor.h"
15 /* VICE code: Store number as little endian. */
16 static void le_store (uint8_t *buf
, uint32_t val
, int len
)
19 for (i
= 0; i
< len
; i
++) {
20 buf
[i
] = (uint8_t) (val
& 0xff);
25 static void wav_notify (void *opaque
, audcnotification_e cmd
)
31 static void wav_destroy (void *opaque
)
33 WAVState
*wav
= opaque
;
36 uint32_t datalen
= wav
->bytes
;
37 uint32_t rifflen
= datalen
+ 36;
38 Monitor
*mon
= cur_mon
;
41 le_store (rlen
, rifflen
, 4);
42 le_store (dlen
, datalen
, 4);
44 if (fseek (wav
->f
, 4, SEEK_SET
)) {
45 monitor_printf (mon
, "wav_destroy: rlen fseek failed\nReason: %s\n",
49 if (fwrite (rlen
, 4, 1, wav
->f
) != 1) {
50 monitor_printf (mon
, "wav_destroy: rlen fwrite failed\nReason %s\n",
54 if (fseek (wav
->f
, 32, SEEK_CUR
)) {
55 monitor_printf (mon
, "wav_destroy: dlen fseek failed\nReason %s\n",
59 if (fwrite (dlen
, 1, 4, wav
->f
) != 4) {
60 monitor_printf (mon
, "wav_destroy: dlen fwrite failed\nReason %s\n",
65 if (fclose (wav
->f
)) {
66 error_report("wav_destroy: fclose failed: %s", strerror(errno
));
73 static void wav_capture (void *opaque
, void *buf
, int size
)
75 WAVState
*wav
= opaque
;
77 if (fwrite (buf
, size
, 1, wav
->f
) != 1) {
78 monitor_printf (cur_mon
, "wav_capture: fwrite error\nReason: %s",
84 static void wav_capture_destroy (void *opaque
)
86 WAVState
*wav
= opaque
;
88 AUD_del_capture (wav
->cap
, wav
);
91 static void wav_capture_info (void *opaque
)
93 WAVState
*wav
= opaque
;
94 char *path
= wav
->path
;
96 monitor_printf (cur_mon
, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
97 wav
->freq
, wav
->bits
, wav
->nchannels
,
98 path
? path
: "<not available>", wav
->bytes
);
101 static struct capture_ops wav_capture_ops
= {
102 .destroy
= wav_capture_destroy
,
103 .info
= wav_capture_info
106 int wav_start_capture (CaptureState
*s
, const char *path
, int freq
,
107 int bits
, int nchannels
)
109 Monitor
*mon
= cur_mon
;
112 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
113 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
114 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
115 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
117 struct audsettings as
;
118 struct audio_capture_ops ops
;
119 int stereo
, bits16
, shift
;
120 CaptureVoiceOut
*cap
;
122 if (bits
!= 8 && bits
!= 16) {
123 monitor_printf (mon
, "incorrect bit count %d, must be 8 or 16\n", bits
);
127 if (nchannels
!= 1 && nchannels
!= 2) {
128 monitor_printf (mon
, "incorrect channel count %d, must be 1 or 2\n",
133 stereo
= nchannels
== 2;
137 as
.nchannels
= 1 << stereo
;
138 as
.fmt
= bits16
? AUD_FMT_S16
: AUD_FMT_U8
;
141 ops
.notify
= wav_notify
;
142 ops
.capture
= wav_capture
;
143 ops
.destroy
= wav_destroy
;
145 wav
= g_malloc0 (sizeof (*wav
));
147 shift
= bits16
+ stereo
;
148 hdr
[34] = bits16
? 0x10 : 0x08;
150 le_store (hdr
+ 22, as
.nchannels
, 2);
151 le_store (hdr
+ 24, freq
, 4);
152 le_store (hdr
+ 28, freq
<< shift
, 4);
153 le_store (hdr
+ 32, 1 << shift
, 2);
155 wav
->f
= fopen (path
, "wb");
157 monitor_printf (mon
, "Failed to open wave file `%s'\nReason: %s\n",
158 path
, strerror (errno
));
163 wav
->path
= g_strdup (path
);
165 wav
->nchannels
= nchannels
;
168 if (fwrite (hdr
, sizeof (hdr
), 1, wav
->f
) != 1) {
169 monitor_printf (mon
, "Failed to write header\nReason: %s\n",
174 cap
= AUD_add_capture (&as
, &ops
, wav
);
176 monitor_printf (mon
, "Failed to add audio capture\n");
182 s
->ops
= wav_capture_ops
;
187 if (fclose (wav
->f
)) {
188 monitor_printf (mon
, "Failed to close wave file\nReason: %s\n",