⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sndheader.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 3 页
字号:
            while (siz > 0) {                snd_file_read(snd->u.file.file, buf, 1);                siz--;            }        }        size = readrevlong(snd->u.file.file, &read_in);        format = readrevshort(snd->u.file.file, &read_in);        switch (format) {          case WAVE_FORMAT_UNKNOWN:            return fail(snd, "file in Microsoft Official Unknown format");          case WAVE_FORMAT_PCM:            break;              case WAVE_FORMAT_ADPCM:            return fail(snd, "file in ADPCM format");          case WAVE_FORMAT_ALAW:            return fail(snd, "file in ALAW format");          case WAVE_FORMAT_MULAW:            return fail(snd, "file in ULAW format");          case WAVE_FORMAT_OKI_ADPCM:            return fail(snd, "file in OKI ADPCM format");          case WAVE_FORMAT_DIGISTD:            return fail(snd, "file in Digistd format");          case WAVE_FORMAT_DIGIFIX:            return fail(snd, "file in Digifix format");          case IBM_FORMAT_MULAW:            return fail(snd, "file in IBM U-law format");          case IBM_FORMAT_ALAW:            return fail(snd, "file in IBM A-law format");          case IBM_FORMAT_ADPCM:            return fail(snd, "file in IBM ADPCM format");          default:            return fail(snd, "file in unknown format");        }               snd->format.channels = readrevshort(snd->u.file.file, &read_in);        snd->format.srate = (double) readrevlong(snd->u.file.file, &read_in);        readrevlong(snd->u.file.file, &read_in);  /* Average bytes/second */        readrevshort(snd->u.file.file, &read_in); /* Block align */        snd->format.bits = readrevshort(snd->u.file.file, &read_in);        snd->format.mode = SND_MODE_PCM;        if (snd->format.bits == 8) snd->format.mode = SND_MODE_UPCM;    /* unsigned */        *flags = SND_HEAD_MODE | SND_HEAD_BITS | SND_HEAD_SRATE |            SND_HEAD_CHANNELS | SND_HEAD_LEN;        /* size is size of "fmt " section; we've read 16 bytes, so         * advance file pointer over any remaining bytes         */        snd->u.file.byte_offset =             snd_file_lseek(snd->u.file.file, size - 16, SND_SEEK_CUR);        /* skip over any other forms until you find "data" */        while (1) {            long n = snd_file_read(snd->u.file.file, buf, 4);            if (n != 4) {                return fail(snd, "missing data portion");            }            if (strncmp("data", buf, 4) == 0) break;            n = readrevlong(snd->u.file.file, &read_in);    /* length of form */            snd->u.file.byte_offset =                 snd_file_lseek(snd->u.file.file, n, SND_SEEK_CUR);        }        snd->u.file.byte_offset += 8; /* "data" and length use 8 bytes */        snd->u.file.current_offset = snd->u.file.byte_offset;        snd->u.file.end_offset = snd->u.file.byte_offset +             readrevlong(snd->u.file.file, &read_in);    } else {        snd->u.file.header = SND_HEAD_NONE;        (*flags) = 0;        resetfile(snd->u.file.file);        read_in = 0;    }        /* If not already determined from file header, assume remainder of file       is sound data */    if (!(*flags & SND_HEAD_LEN)) {        snd->u.file.end_offset = snd->u.file.byte_offset = read_in;        snd->u.file.current_offset = snd->u.file.byte_offset;        snd->u.file.end_offset = len;        *flags |= SND_HEAD_LEN;    }    return SND_SUCCESS;}/* write_zeros -- add zeros to end of file *//**/void write_zeros(int fout, long n){    long zero = 0;    while (n > 0) {        /* don't put min() in the arg list of write on an RS6K */        /* there seems to be a compiler bug */        long len = min(n, sizeof(long));        snd_file_write(fout, (char *) &zero, len);        n -= sizeof(long);    }}/* write_ircam_start -- write an IRCAM header at current file position *//* * length is the total length of the header to be written; this is normally * SIZEOF_IRCAM_HEADER, but in the case of the hybrid CMIX headers, length * will be shorter to accommodate the NeXT header prefix */void write_ircam_start(snd_type snd, long length){    short encoding;        writelong(snd->u.file.file, IRCAM_SND_MAGIC);    writefloat(snd->u.file.file, (float) snd->format.srate);    writelong(snd->u.file.file, snd->format.channels);    writelong(snd->u.file.file, snd->format.bits >> 3);    /* now write the "CODE" section */    writeshort(snd->u.file.file, IRCAM_SND_AUDIOENCODE);    writeshort(snd->u.file.file, 3 * sizeof(short));    /* size of this record */    if (snd->format.bits == 8) {        encoding = IRCAM_SND_CHAR;        if (snd->format.mode == SND_MODE_ULAW) encoding = IRCAM_SND_ULAW;        if (snd->format.mode == SND_MODE_ALAW) {            snd_warn("ALAW not implemented, writing 8-bit PCM\n");        }    } else if (snd->format.bits == 16) {        encoding = IRCAM_SND_SHORT;    } else if (snd->format.bits == 32) {        encoding = IRCAM_SND_FLOAT;        if (snd->format.mode == SND_MODE_PCM) encoding = IRCAM_SND_LONG;    }    writeshort(snd->u.file.file, encoding);        /* end the "CODE" section */    writeshort(snd->u.file.file, IRCAM_SND_END);    writeshort(snd->u.file.file, 2 * sizeof(short));        /* write filler */    length -= ( 16 /* head */ + 6 /* AudioEncode */ + 4 /* End */ );        write_zeros(snd->u.file.file, length);}/* write_next_start -- write a NeXT header *//* * Note: uses length for Length field, but does not fill with zeros. * Instead, this routine writes only the NeXT 24 byte header. */void write_next_start(snd_type snd, long length){    short encoding;        writelong(snd->u.file.file, NEXT_SND_MAGIC);    /* header size matches cmix's bsd format */    writelong(snd->u.file.file, length);    writelong(snd->u.file.file, 0); /* data size, 0 -> unspecified */    if (snd->format.bits == 8) {        encoding = NEXT_SND_FORMAT_LINEAR_8;        if (snd->format.mode == SND_MODE_ULAW)            encoding = NEXT_SND_FORMAT_ULAW_8;        if (snd->format.mode == SND_MODE_ALAW) {            snd_warn("ALAW not implemented, writing 8-bit PCM\n");        }    } else if (snd->format.bits == 16) {        encoding = NEXT_SND_FORMAT_LINEAR_16;    } else if (snd->format.bits == 32) {        encoding = NEXT_SND_FORMAT_FLOAT;        if (snd->format.mode == SND_MODE_PCM)            encoding = NEXT_SND_FORMAT_LINEAR_32;    }    writelong(snd->u.file.file, encoding);    writelong(snd->u.file.file, (long) (snd->format.srate + 0.5));    writelong(snd->u.file.file, snd->format.channels);}/* snd_write_header -- write header, position file for sample data *//**/void snd_write_header(snd_type snd, long *flags){    long nframes = 0x7f000000;    long bytes_per_frame = snd_bytes_per_frame(snd);        /* end_offset will keep track of how much data written so far */    snd->u.file.end_offset = 0;        switch (snd->u.file.header) {      case SND_HEAD_NONE:        break;      case SND_HEAD_AIFF: {        int hsize =            12 /* bytes at beginning */ +             8 /*COMM hdr*/ + 18 /*COMM chunk*/ +            8 /*SSND hdr*/ + 8 /*SSND chunk*/;        if (snd->format.bits != 8 && snd->format.bits != 16) {            char msg[64];            sprintf(msg, "Warning: using 16 bits per sample instead of %d\n",                         snd->format.bits);            snd_warn(msg);            snd->format.bits = 16;            bytes_per_frame = snd_bytes_per_frame(snd);        }        snd_file_write(snd->u.file.file, "FORM", 4); /* IFF header */        /* (bogus) file size: */        writelong(snd->u.file.file,                   hsize + nframes * bytes_per_frame);        snd_file_write(snd->u.file.file, "AIFF", 4); /* File type */                /* COMM chunk -- describes encoding (and #frames) */        snd_file_write(snd->u.file.file, "COMM", 4);        writelong(snd->u.file.file, 18); /* COMM chunk size */        writeshort(snd->u.file.file, (short) snd->format.channels); /* nchannels */        writelong(snd->u.file.file, nframes); /* number of frames */        writeshort(snd->u.file.file, (short) snd->format.bits); /* sample width, in bits */        write_ieee_extended(snd->u.file.file, snd->format.srate);        /* SSND chunk -- describes data */        snd_file_write(snd->u.file.file, "SSND", 4);        writelong(snd->u.file.file,                   8 + nframes * bytes_per_frame); /* chunk size */        writelong(snd->u.file.file, 0); /* offset */        writelong(snd->u.file.file, 0); /* block size */        snd->u.file.byte_offset = hsize;        /*      printf("snd_write_header AIFF, byte_offset = %ld\n",                snd_lseek(snd->u.file.file, (off_t) 0, SND_SEEK_CUR)); */        break; }      case SND_HEAD_IRCAM:         write_ircam_start(snd, SIZEOF_IRCAM_HEADER);        snd->u.file.byte_offset = SIZEOF_IRCAM_HEADER;        break;      case SND_HEAD_NEXT:        /* for compatibility with CMIX, we will always write an IRCAM         * header after the NeXT header, and use 1024 bytes of header.         */        write_next_start(snd, SIZEOF_IRCAM_HEADER);        write_ircam_start(snd, SIZEOF_IRCAM_HEADER - 24);        snd->u.file.byte_offset = SIZEOF_IRCAM_HEADER;        break;      case SND_HEAD_WAVE:        snd_file_write(snd->u.file.file, "RIFF", 4);        writerevlong(snd->u.file.file, 12+18+8 + nframes * bytes_per_frame);        snd_file_write(snd->u.file.file, "WAVE", 4);        snd_file_write(snd->u.file.file, "fmt ", 4);        writerevlong(snd->u.file.file, 18L);        switch (snd->format.mode) /* Format type */        {            case SND_MODE_ADPCM:                writerevshort(snd->u.file.file, 2);                break;            case SND_MODE_PCM:            case SND_MODE_UPCM:                writerevshort(snd->u.file.file, 1);                break;            case SND_MODE_ULAW:                writerevshort(snd->u.file.file, 7);                break;            case SND_MODE_ALAW:                writerevshort(snd->u.file.file, 6);                break;            case SND_MODE_UNKNOWN:            case SND_MODE_FLOAT:            default:                writerevshort(snd->u.file.file, 0);                break;        }        writerevshort(snd->u.file.file, (short) snd->format.channels); /* Number of channels */        writerevlong(snd->u.file.file, (long) (snd->format.srate + 0.5)); /* Samples per second */        writerevlong(snd->u.file.file,  (((long) snd->format.srate) * bytes_per_frame)); /* Bytes per second*/        writerevshort(snd->u.file.file, (short) bytes_per_frame); /* Block alignment */        writerevshort(snd->u.file.file, (short) snd->format.bits); /* Bits per sample */        writerevshort(snd->u.file.file, (short) 0); /* Size of needed extra data */        snd_file_write(snd->u.file.file, "data", 4);        writerevlong(snd->u.file.file, (long) (nframes * bytes_per_frame));        snd->u.file.byte_offset = 46;        break;      default:        break;    }    snd->u.file.end_offset = snd->u.file.byte_offset;}void write_sndheader_finish(snd_type snd){    long n;    switch (snd->u.file.header) {      case SND_HEAD_NONE:        break;      case SND_HEAD_AIFF: {        int hsize =            8 /*COMM hdr*/ + 18 /*COMM chunk*/ +            8 /*SSND hdr*/ + 12 /*SSND chunk*/;        int datasize = snd->u.file.end_offset - hsize - 8;                /* get the current position = file size */        n = snd_file_lseek(snd->u.file.file, 0, SND_SEEK_CUR);        if (n != snd->u.file.end_offset) {            char str[80];            sprintf(str,                    "Actual file size %ld does not match predicted size %ld\n",                    n, snd->u.file.end_offset);            fail(snd, str);        }        /* write filesize in the header */        snd_file_lseek(snd->u.file.file, 4, SND_SEEK_SET);        writelong(snd->u.file.file, n - 8 /* 'FORM'+size do not count */);                /* write number of frames in COMM chunk */        snd_file_lseek(snd->u.file.file, (4 /* 'AIFF' */ + 4 /* 'COMM' */ +                                          4 /* size */ + 2 /* channels */),               SND_SEEK_CUR);        writelong(snd->u.file.file,                   (n - (hsize + 8)) / snd_bytes_per_frame(snd));                /* write size in SSND chunk */        snd_file_lseek(snd->u.file.file, (2 /* snd->format.bits */ +                                          10 /* sr */ + 4 /* 'SSND' */),               SND_SEEK_CUR);        writelong(snd->u.file.file, 8 + datasize); /* chunk size */        break; }      case SND_HEAD_IRCAM:        break;      case SND_HEAD_NEXT:        break;      case SND_HEAD_WAVE:        /* get the current position = file size */        n = snd_file_lseek(snd->u.file.file, 0, SND_SEEK_CUR);        /* back to the top */        snd_file_lseek(snd->u.file.file, 4, SND_SEEK_SET);        writerevlong(snd->u.file.file, n - 8);  /* file size - ['RIFF', len] */        snd_file_lseek(snd->u.file.file, 42, SND_SEEK_SET);        writerevlong(snd->u.file.file, n - 46); /* data size */        break;      default:        break;    }}double read_ieee_extended(snd_type snd){    unsigned char buf[10];    if (snd_file_read(snd->u.file.file, (char *) buf, 10L) != 10)        fail(snd, "EOF while reading IEEE extended number");    return ConvertFromIeeeExtended(buf);}void write_ieee_extended(int file, double x){    char buf[10];    ConvertToIeeeExtended(x, buf);    /*      report("converted %g to %o %o %o %o %o %o %o %o %o %o",      x,      buf[0], buf[1], buf[2], buf[3], buf[4],      buf[5], buf[6], buf[7], buf[8], buf[9]);      */    snd_file_write(file, buf, 10);}char *mode_string[] = { "ADPCM", "PCM", "ULAW", "ALAW", "Float", "UPCM", "Unknown" };char *mode_to_string(long mode){    if (mode < 0 || mode >= SND_NUM_MODES) return "InvalidData";    else return mode_string[mode];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -