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 fprintf (stderr
, "wav_destroy: fclose failed: %s",
74 static void wav_capture (void *opaque
, void *buf
, int size
)
76 WAVState
*wav
= opaque
;
78 if (fwrite (buf
, size
, 1, wav
->f
) != 1) {
79 monitor_printf (cur_mon
, "wav_capture: fwrite error\nReason: %s",
85 static void wav_capture_destroy (void *opaque
)
87 WAVState
*wav
= opaque
;
89 AUD_del_capture (wav
->cap
, wav
);
92 static void wav_capture_info (void *opaque
)
94 WAVState
*wav
= opaque
;
95 char *path
= wav
->path
;
97 monitor_printf (cur_mon
, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
98 wav
->freq
, wav
->bits
, wav
->nchannels
,
99 path
? path
: "<not available>", wav
->bytes
);
102 static struct capture_ops wav_capture_ops
= {
103 .destroy
= wav_capture_destroy
,
104 .info
= wav_capture_info
107 int wav_start_capture (CaptureState
*s
, const char *path
, int freq
,
108 int bits
, int nchannels
)
110 Monitor
*mon
= cur_mon
;
113 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
114 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
115 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
116 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
118 struct audsettings as
;
119 struct audio_capture_ops ops
;
120 int stereo
, bits16
, shift
;
121 CaptureVoiceOut
*cap
;
123 if (bits
!= 8 && bits
!= 16) {
124 monitor_printf (mon
, "incorrect bit count %d, must be 8 or 16\n", bits
);
128 if (nchannels
!= 1 && nchannels
!= 2) {
129 monitor_printf (mon
, "incorrect channel count %d, must be 1 or 2\n",
134 stereo
= nchannels
== 2;
138 as
.nchannels
= 1 << stereo
;
139 as
.fmt
= bits16
? AUD_FMT_S16
: AUD_FMT_U8
;
142 ops
.notify
= wav_notify
;
143 ops
.capture
= wav_capture
;
144 ops
.destroy
= wav_destroy
;
146 wav
= g_malloc0 (sizeof (*wav
));
148 shift
= bits16
+ stereo
;
149 hdr
[34] = bits16
? 0x10 : 0x08;
151 le_store (hdr
+ 22, as
.nchannels
, 2);
152 le_store (hdr
+ 24, freq
, 4);
153 le_store (hdr
+ 28, freq
<< shift
, 4);
154 le_store (hdr
+ 32, 1 << shift
, 2);
156 wav
->f
= fopen (path
, "wb");
158 monitor_printf (mon
, "Failed to open wave file `%s'\nReason: %s\n",
159 path
, strerror (errno
));
164 wav
->path
= g_strdup (path
);
166 wav
->nchannels
= nchannels
;
169 if (fwrite (hdr
, sizeof (hdr
), 1, wav
->f
) != 1) {
170 monitor_printf (mon
, "Failed to write header\nReason: %s\n",
175 cap
= AUD_add_capture (&as
, &ops
, wav
);
177 monitor_printf (mon
, "Failed to add audio capture\n");
183 s
->ops
= wav_capture_ops
;
188 if (fclose (wav
->f
)) {
189 monitor_printf (mon
, "Failed to close wave file\nReason: %s\n",