(linenum→info "unix/slp.c:2238")

qemu/0.9.1/audio/wavcapture.c

    1: #include "hw/hw.h"
    2: #include "console.h"
    3: #include "audio.h"
    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: 
   39:     if (wav->f) {
   40:         le_store (rlen, rifflen, 4);
   41:         le_store (dlen, datalen, 4);
   42: 
   43:         qemu_fseek (wav->f, 4, SEEK_SET);
   44:         qemu_put_buffer (wav->f, rlen, 4);
   45: 
   46:         qemu_fseek (wav->f, 32, SEEK_CUR);
   47:         qemu_put_buffer (wav->f, dlen, 4);
   48:         qemu_fclose (wav->f);
   49:     }
   50: 
   51:     qemu_free (wav->path);
   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:     };
   94:     audsettings_t as;
   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:     if (!wav) {
  124:         term_printf ("Could not allocate memory for wav capture (%zu bytes)",
  125:                      sizeof (*wav));
  126:         return -1;
  127:     }
  128: 
  129:     shift = bits16 + stereo;
  130:     hdr[34] = bits16 ? 0x10 : 0x08;
  131: 
  132:     le_store (hdr + 22, as.nchannels, 2);
  133:     le_store (hdr + 24, freq, 4);
  134:     le_store (hdr + 28, freq << shift, 4);
  135:     le_store (hdr + 32, 1 << shift, 2);
  136: 
  137:     wav->f = qemu_fopen (path, "wb");
  138:     if (!wav->f) {
  139:         term_printf ("Failed to open wave file `%s'\nReason: %s\n",
  140:                      path, strerror (errno));
  141:         qemu_free (wav);
  142:         return -1;
  143:     }
  144: 
  145:     wav->path = qemu_strdup (path);
  146:     wav->bits = bits;
  147:     wav->nchannels = nchannels;
  148:     wav->freq = freq;
  149: 
  150:     qemu_put_buffer (wav->f, hdr, sizeof (hdr));
  151: 
  152:     cap = AUD_add_capture (NULL, &as, &ops, wav);
  153:     if (!cap) {
  154:         term_printf ("Failed to add audio capture\n");
  155:         qemu_free (wav->path);
  156:         qemu_fclose (wav->f);
  157:         qemu_free (wav);
  158:         return -1;
  159:     }
  160: 
  161:     wav->cap = cap;
  162:     s->opaque = wav;
  163:     s->ops = wav_capture_ops;
  164:     return 0;
  165: }
Syntax (Markdown)