📄 sound.c
字号:
if (!(mus_file_probe(arg))) mus_error(MUS_CANT_OPEN_FILE, S_mus_sound_open_input " can't open %s: %s", arg, STRERROR(errno)); else { sound_file *sf = NULL; mus_sound_initialize(); sf = find_sound_file(arg); if (!sf) sf = read_sound_file_header(arg); if (sf) { fd = mus_file_open_read(arg); mus_file_open_descriptors(fd, arg, sf->data_format, sf->datum_size, sf->data_location, sf->chans, sf->header_type); lseek(fd, sf->data_location, SEEK_SET); } } return(fd);}int mus_sound_open_output(const char *arg, int srate, int chans, int data_format, int header_type, const char *comment){ int fd = MUS_ERROR, err, comlen = 0; if (comment) comlen = strlen(comment); mus_sound_initialize(); mus_sound_forget(arg); err = mus_header_write(arg, header_type, srate, chans, 0, 0, data_format, comment, comlen); if (err != MUS_ERROR) { fd = mus_file_open_write(arg); if (fd != -1) mus_file_open_descriptors(fd, arg, data_format, mus_bytes_per_sample(data_format), mus_header_data_location(), chans, header_type); } return(fd);}int mus_sound_reopen_output(const char *arg, int chans, int format, int type, off_t data_loc){ int fd; mus_sound_initialize(); fd = mus_file_reopen_write(arg); if (fd != -1) mus_file_open_descriptors(fd, arg, format, mus_bytes_per_sample(format), data_loc, chans, type); return(fd);}int mus_sound_close_input(int fd) { return(mus_file_close(fd)); /* this closes the clm file descriptors */}int mus_sound_close_output(int fd, off_t bytes_of_data) { char *name; name = mus_file_fd_name(fd); if (name) { int err = MUS_ERROR, old_type; char *fname; fname = strdup(name); /* strdup defined, if necessary, in io.c */ old_type = mus_file_header_type(fd); err = mus_file_close(fd); /* this frees the original fd->name, so we copied above */ /* fd is NULL now */ mus_sound_forget(fname); mus_header_change_data_size(fname, old_type, bytes_of_data); free(fname); return(err); } return(MUS_ERROR);}typedef enum {SF_CHANS, SF_SRATE, SF_TYPE, SF_FORMAT, SF_LOCATION, SF_SIZE} sf_field_t;static int mus_sound_set_field(const char *arg, sf_field_t field, int val){ sound_file *sf; sf = getsf(arg); if (sf) { switch (field) { case SF_CHANS: sf->chans = val; break; case SF_SRATE: sf->srate = val; break; case SF_TYPE: sf->header_type = val; break; case SF_FORMAT: sf->data_format = val; sf->datum_size = mus_bytes_per_sample(val); break; default: return(MUS_ERROR); break; } return(MUS_NO_ERROR); } return(MUS_ERROR);}static int mus_sound_set_off_t_field(const char *arg, sf_field_t field, off_t val){ sound_file *sf; sf = getsf(arg); if (sf) { switch (field) { case SF_SIZE: sf->samples = val; break; case SF_LOCATION: sf->data_location = val; break; default: return(MUS_ERROR); break; } return(MUS_NO_ERROR); } return(MUS_ERROR);}int mus_sound_set_chans(const char *arg, int val) {return(mus_sound_set_field(arg, SF_CHANS, val));}int mus_sound_set_srate(const char *arg, int val) {return(mus_sound_set_field(arg, SF_SRATE, val));}int mus_sound_set_header_type(const char *arg, int val) {return(mus_sound_set_field(arg, SF_TYPE, val));}int mus_sound_set_data_format(const char *arg, int val) {return(mus_sound_set_field(arg, SF_FORMAT, val));}int mus_sound_set_data_location(const char *arg, off_t val) {return(mus_sound_set_off_t_field(arg, SF_LOCATION, val));}int mus_sound_set_samples(const char *arg, off_t val) {return(mus_sound_set_off_t_field(arg, SF_SIZE, val));}int mus_sound_override_header(const char *arg, int srate, int chans, int format, int type, off_t location, off_t size){ sound_file *sf; /* perhaps once a header has been over-ridden, we should not reset the relevant fields upon re-read? */ sf = getsf(arg); if (sf) { if (location != -1) sf->data_location = location; if (size != -1) sf->samples = size; if (format != -1) { sf->data_format = format; sf->datum_size = mus_bytes_per_sample(format); } if (srate != -1) sf->srate = srate; if (chans != -1) sf->chans = chans; if (type != -1) sf->header_type = type; return(MUS_NO_ERROR); } return(MUS_ERROR);}bool mus_sound_maxamp_exists(const char *ifile){ sound_file *sf; bool val = false; sf = getsf(ifile); val = ((sf) && (sf->maxamps)); return(val);}off_t mus_sound_maxamps(const char *ifile, int chans, mus_sample_t *vals, off_t *times){ int ifd, ichans, chn, j; int i, bufnum; off_t n, frames, curframes; mus_sample_t abs_samp; mus_sample_t *buffer, *samp; off_t *time; mus_sample_t **ibufs; sound_file *sf; sf = getsf(ifile); if (sf->chans <= 0) return(MUS_ERROR); if ((sf) && (sf->maxamps)) { if (chans > sf->chans) ichans = sf->chans; else ichans = chans; for (chn = 0; chn < ichans; chn++) { times[chn] = sf->maxtimes[chn]; vals[chn] = sf->maxamps[chn]; } frames = sf->samples / sf->chans; return(frames); } ifd = mus_sound_open_input(ifile); if (ifd == MUS_ERROR) return(MUS_ERROR); ichans = mus_sound_chans(ifile); frames = mus_sound_frames(ifile); if (frames == 0) { mus_sound_close_input(ifd); return(0); } mus_file_seek_frame(ifd, 0); ibufs = (mus_sample_t **)CALLOC(ichans, sizeof(mus_sample_t *)); bufnum = 8192; for (j = 0; j < ichans; j++) ibufs[j] = (mus_sample_t *)CALLOC(bufnum, sizeof(mus_sample_t)); time = (off_t *)CALLOC(ichans, sizeof(off_t)); samp = (mus_sample_t *)CALLOC(ichans, sizeof(mus_sample_t)); for (n = 0; n < frames; n += bufnum) { if ((n + bufnum) < frames) curframes = bufnum; else curframes = (frames - n); mus_file_read(ifd, 0, curframes - 1, ichans, ibufs); for (chn = 0; chn < ichans; chn++) { buffer = (mus_sample_t *)(ibufs[chn]); for (i = 0; i < curframes; i++) { abs_samp = mus_sample_abs(buffer[i]); if (abs_samp > samp[chn]) { time[chn] = i + n; samp[chn] = abs_samp; } } } } mus_sound_close_input(ifd); mus_sound_set_maxamps(ifile, ichans, samp, time); /* save the complete set */ if (ichans > chans) ichans = chans; for (chn = 0; chn < ichans; chn++) { times[chn] = time[chn]; vals[chn] = samp[chn]; } FREE(time); FREE(samp); for (j = 0; j < ichans; j++) FREE(ibufs[j]); FREE(ibufs); return(frames);}int mus_sound_set_maxamps(const char *ifile, int chans, mus_sample_t *vals, off_t *times){ sound_file *sf; sf = getsf(ifile); if (sf) { int i, ichans = 0; if (sf->maxamps) { if (chans > sf->chans) ichans = sf->chans; else ichans = chans; for (i = 0; i < ichans; i++) { sf->maxtimes[i] = times[i]; sf->maxamps[i] = vals[i]; } } else { ichans = mus_sound_chans(ifile); if (sf->maxamps == NULL) { sf->maxamps = (mus_sample_t *)CALLOC(ichans, sizeof(mus_sample_t)); sf->maxtimes = (off_t *)CALLOC(ichans, sizeof(off_t)); } if (ichans > chans) ichans = chans; for (i = 0; i < ichans; i++) { sf->maxtimes[i] = times[i]; sf->maxamps[i] = vals[i]; } } return(MUS_NO_ERROR); } return(MUS_ERROR);}int mus_file_to_array(const char *filename, int chan, int start, int samples, mus_sample_t *array){ int ifd, chans, total_read; mus_sample_t **bufs; ifd = mus_sound_open_input(filename); if (ifd == MUS_ERROR) return(MUS_ERROR); chans = mus_sound_chans(filename); if (chan >= chans) { mus_sound_close_input(ifd); return(mus_error(MUS_NO_SUCH_CHANNEL, "mus_file_to_array can't read %s channel %d (file has %d chans)", filename, chan, chans)); } bufs = (mus_sample_t **)CALLOC(chans, sizeof(mus_sample_t *)); bufs[chan] = array; mus_file_seek_frame(ifd, start); total_read = mus_file_read_any(ifd, 0, chans, samples, bufs, bufs); mus_sound_close_input(ifd); FREE(bufs); return(total_read);}char *mus_array_to_file_with_error(const char *filename, mus_sample_t *ddata, int len, int srate, int channels){ /* put ddata into a sound file, taking byte order into account */ /* assume ddata is interleaved already if more than one channel */ int fd, err = MUS_NO_ERROR; mus_sample_t *bufs[1]; mus_sound_forget(filename); fd = mus_file_create(filename); if (fd == -1) return("mus_array_to_file can't create output file"); err = mus_file_open_descriptors(fd, filename, MUS_OUT_FORMAT, mus_bytes_per_sample(MUS_OUT_FORMAT), 28, channels, MUS_NEXT); if (err != MUS_ERROR) { err = mus_header_write_next_header(fd, srate, channels, 28, len /* out chans = 1?? */, MUS_OUT_FORMAT, NULL, 0); if (err != MUS_ERROR) { bufs[0] = ddata; err = mus_file_write(fd, 0, len - 1, 1, bufs); /* 1 = chans?? */ } } mus_file_close(fd); if (err == MUS_ERROR) return("mus_array_to_file write error"); return(NULL);}int mus_array_to_file(const char *filename, mus_sample_t *ddata, int len, int srate, int channels){ char *errmsg; errmsg = mus_array_to_file_with_error(filename, ddata, len, srate, channels); if (errmsg) return(mus_error(MUS_CANT_OPEN_FILE, errmsg)); return(MUS_NO_ERROR);}int mus_file_to_float_array(const char *filename, int chan, off_t start, int samples, Float *array){#if SNDLIB_USE_FLOATS return(mus_file_to_array(filename, chan, start, samples, array));#else mus_sample_t *idata; int i, len; idata = (mus_sample_t *)CALLOC(samples, sizeof(mus_sample_t)); len = mus_file_to_array(filename, chan, start, samples, idata); if (len != -1) for (i = 0; i < samples; i++) array[i] = MUS_SAMPLE_TO_FLOAT(idata[i]); FREE(idata); return(len);#endif}int mus_float_array_to_file(const char *filename, Float *ddata, int len, int srate, int channels){ char *errmsg;#if SNDLIB_USE_FLOATS errmsg = mus_array_to_file_with_error(filename, ddata, len, srate, channels);#else mus_sample_t *idata; int i; idata = (mus_sample_t *)CALLOC(len, sizeof(mus_sample_t)); for (i = 0; i < len; i++) idata[i] = MUS_FLOAT_TO_SAMPLE(ddata[i]); errmsg = mus_array_to_file_with_error(filename, idata, len, srate, channels); FREE(idata);#endif if (errmsg) return(mus_error(MUS_CANT_OPEN_FILE, errmsg)); return(MUS_NO_ERROR);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -