Annotation of qemu/audio/wavcapture.c, revision 1.1.1.1

1.1       root        1: #include "vl.h"
                      2: 
                      3: typedef struct {
                      4:     QEMUFile *f;
                      5:     int bytes;
                      6:     char *path;
                      7:     int freq;
                      8:     int bits;
                      9:     int nchannels;
                     10:     CaptureVoiceOut *cap;
                     11: } WAVState;
                     12: 
                     13: /* VICE code: Store number as little endian. */
                     14: static void le_store (uint8_t *buf, uint32_t val, int len)
                     15: {
                     16:     int i;
                     17:     for (i = 0; i < len; i++) {
                     18:         buf[i] = (uint8_t) (val & 0xff);
                     19:         val >>= 8;
                     20:     }
                     21: }
                     22: 
                     23: static void wav_notify (void *opaque, audcnotification_e cmd)
                     24: {
                     25:     (void) opaque;
                     26:     (void) cmd;
                     27: }
                     28: 
                     29: static void wav_destroy (void *opaque)
                     30: {
                     31:     WAVState *wav = opaque;
                     32:     uint8_t rlen[4];
                     33:     uint8_t dlen[4];
                     34:     uint32_t datalen = wav->bytes;
                     35:     uint32_t rifflen = datalen + 36;
                     36: 
                     37:     if (!wav->f) {
                     38:         return;
                     39:     }
                     40: 
                     41:     le_store (rlen, rifflen, 4);
                     42:     le_store (dlen, datalen, 4);
                     43: 
                     44:     qemu_fseek (wav->f, 4, SEEK_SET);
                     45:     qemu_put_buffer (wav->f, rlen, 4);
                     46: 
                     47:     qemu_fseek (wav->f, 32, SEEK_CUR);
                     48:     qemu_put_buffer (wav->f, dlen, 4);
                     49:     fclose (wav->f);
                     50:     if (wav->path) {
                     51:         qemu_free (wav->path);
                     52:     }
                     53: }
                     54: 
                     55: static void wav_capture (void *opaque, void *buf, int size)
                     56: {
                     57:     WAVState *wav = opaque;
                     58: 
                     59:     qemu_put_buffer (wav->f, buf, size);
                     60:     wav->bytes += size;
                     61: }
                     62: 
                     63: static void wav_capture_destroy (void *opaque)
                     64: {
                     65:     WAVState *wav = opaque;
                     66: 
                     67:     AUD_del_capture (wav->cap, wav);
                     68: }
                     69: 
                     70: static void wav_capture_info (void *opaque)
                     71: {
                     72:     WAVState *wav = opaque;
                     73:     char *path = wav->path;
                     74: 
                     75:     term_printf ("Capturing audio(%d,%d,%d) to %s: %d bytes\n",
                     76:                  wav->freq, wav->bits, wav->nchannels,
                     77:                  path ? path : "<not available>", wav->bytes);
                     78: }
                     79: 
                     80: static struct capture_ops wav_capture_ops = {
                     81:     .destroy = wav_capture_destroy,
                     82:     .info = wav_capture_info
                     83: };
                     84: 
                     85: int wav_start_capture (CaptureState *s, const char *path, int freq,
                     86:                        int bits, int nchannels)
                     87: {
                     88:     WAVState *wav;
                     89:     uint8_t hdr[] = {
                     90:         0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
                     91:         0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
                     92:         0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
                     93:         0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
                     94:     };
                     95:     audsettings_t as;
                     96:     struct audio_capture_ops ops;
                     97:     int stereo, bits16, shift;
                     98:     CaptureVoiceOut *cap;
                     99: 
                    100:     if (bits != 8 && bits != 16) {
                    101:         term_printf ("incorrect bit count %d, must be 8 or 16\n", bits);
                    102:         return -1;
                    103:     }
                    104: 
                    105:     if (nchannels != 1 && nchannels != 2) {
                    106:         term_printf ("incorrect channel count %d, must be 1 or 2\n",
                    107:                      nchannels);
                    108:         return -1;
                    109:     }
                    110: 
                    111:     stereo = nchannels == 2;
                    112:     bits16 = bits == 16;
                    113: 
                    114:     as.freq = freq;
                    115:     as.nchannels = 1 << stereo;
                    116:     as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
                    117:     as.endianness = 0;
                    118: 
                    119:     ops.notify = wav_notify;
                    120:     ops.capture = wav_capture;
                    121:     ops.destroy = wav_destroy;
                    122: 
                    123:     wav = qemu_mallocz (sizeof (*wav));
                    124:     if (!wav) {
                    125:         term_printf ("Could not allocate memory for wav capture (%zu bytes)",
                    126:                      sizeof (*wav));
                    127:         return -1;
                    128:     }
                    129: 
                    130:     shift = bits16 + stereo;
                    131:     hdr[34] = bits16 ? 0x10 : 0x08;
                    132: 
                    133:     le_store (hdr + 22, as.nchannels, 2);
                    134:     le_store (hdr + 24, freq, 4);
                    135:     le_store (hdr + 28, freq << shift, 4);
                    136:     le_store (hdr + 32, 1 << shift, 2);
                    137: 
                    138:     wav->f = fopen (path, "wb");
                    139:     if (!wav->f) {
                    140:         term_printf ("Failed to open wave file `%s'\nReason: %s\n",
                    141:                      path, strerror (errno));
                    142:         qemu_free (wav);
                    143:         return -1;
                    144:     }
                    145: 
                    146:     wav->path = qemu_strdup (path);
                    147:     wav->bits = bits;
                    148:     wav->nchannels = nchannels;
                    149:     wav->freq = freq;
                    150: 
                    151:     qemu_put_buffer (wav->f, hdr, sizeof (hdr));
                    152: 
                    153:     cap = AUD_add_capture (NULL, &as, &ops, wav);
                    154:     if (!cap) {
                    155:         term_printf ("Failed to add audio capture\n");
                    156:         qemu_free (wav);
                    157:         return -1;
                    158:     }
                    159: 
                    160:     wav->cap = cap;
                    161:     s->opaque = wav;
                    162:     s->ops = wav_capture_ops;
                    163:     return 0;
                    164: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.