Annotation of qemu/audio/wavcapture.c, revision 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.