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

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

unix.superglobalmegacorp.com

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