📄 io.c
字号:
int mus_file_read_chans(int tfd, int beg, int end, int chans, mus_sample_t **bufs, mus_sample_t **cm){ /* an optimization of mus_file_read -- just reads the desired channels */ int num, rtn, i, k; num = (end - beg + 1); rtn = mus_read_any_1(tfd, beg, chans, num, bufs, cm, NULL); if (rtn == MUS_ERROR) return(MUS_ERROR); if (rtn < num) for (k = 0; k < chans; k++) if ((cm == NULL) || (cm[k])) { mus_sample_t *buffer; buffer = bufs[k]; i = rtn + beg; memset((void *)(buffer + i), 0, (end - i + 1) * sizeof(mus_sample_t)); } return(num);}/* ---------------- write ---------------- */static int checked_write(int tfd, char *buf, int chars){ int bytes; bytes = write(tfd, buf, chars); if (bytes != chars) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, "mus_write: no file descriptors!")); fd = io_fds[tfd]; if (fd->data_format == MUS_UNKNOWN) return(mus_error(MUS_FILE_CLOSED, "attempt to write closed file %s", fd->name)); else return(mus_error(MUS_WRITE_ERROR, "mus_write: write error for %s%s%s: only %d of %d bytes written", fd->name, (errno) ? ": " : "", (errno) ? STRERROR(errno) : "", bytes, chars)); } return(MUS_NO_ERROR);}static int mus_write_1(int tfd, int beg, int end, int chans, mus_sample_t **bufs, char *inbuf, bool clipped){ int loclim, c3; int err; io_fd *fd; int bytes, j, k, lim, siz, leftover, loc, bk, val, oldloc, buflim, siz_chans, cliploc, data_format; bool clipping = false; unsigned char *jchar; char *charbuf = NULL; bool to_buffer = false; mus_sample_t *buffer; if (chans <= 0) return(0); if (inbuf) to_buffer = true; if (!to_buffer) { if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, "mus_write: no file descriptors!")); fd = io_fds[tfd]; if (fd->data_format == MUS_UNKNOWN) return(mus_error(MUS_FILE_CLOSED, "mus_write: invalid data format for %s", fd->name)); siz = fd->bytes_per_sample; data_format = fd->data_format; clipping = fd->clipping; if ((data_format == MUS_OUT_FORMAT) && (chans == 1) && (!clipping) && (beg == 0)) { bytes = (end + 1) * siz; return(checked_write(tfd, (char *)(bufs[0]), bytes)); } charbuf = (char *)CALLOC(BUFLIM, sizeof(char)); if (charbuf == NULL) return(mus_error(MUS_MEMORY_ALLOCATION_FAILED, "mus_write: IO buffer allocation failed")); } else { charbuf = inbuf; siz = mus_bytes_per_sample(tfd); data_format = tfd; /* in this case, tfd is the data format (see mus_file_write_buffer below) -- this should be changed! */ clipping = clipped; } lim = (end - beg + 1); siz_chans = siz * chans; leftover = lim * siz_chans; k = (BUFLIM) % siz_chans; if (k != 0) buflim = (BUFLIM) - k; else buflim = BUFLIM; loc = beg; while (leftover > 0) { bytes = leftover; if (bytes > buflim) { leftover = (bytes - buflim); bytes = buflim; } else leftover = 0; lim = (int)(bytes / siz_chans); /* see note above */ oldloc = loc; for (k = 0; k < chans; k++) { if (bufs[k] == NULL) continue; loc = oldloc; buffer = (mus_sample_t *)(bufs[k]); if (clipping) { cliploc = oldloc; for (j = 0; j < lim; j++, cliploc++) if (buffer[cliploc] > MUS_SAMPLE_MAX) buffer[cliploc] = MUS_SAMPLE_MAX; else if (buffer[cliploc] < MUS_SAMPLE_MIN) buffer[cliploc] = MUS_SAMPLE_MIN; } loclim = loc + lim; jchar = (unsigned char *)charbuf; /* if to_buffer we should add the loop offset here, or never loop */ jchar += (k * siz); switch (data_format) { case MUS_BSHORT: for (; loc < loclim; loc++, jchar += siz_chans) m_set_big_endian_short(jchar, MUS_SAMPLE_TO_SHORT(buffer[loc])); break; case MUS_LSHORT: for (; loc < loclim; loc++, jchar += siz_chans) m_set_little_endian_short(jchar, MUS_SAMPLE_TO_SHORT(buffer[loc])); break; case MUS_BINT: for (; loc < loclim; loc++, jchar += siz_chans) m_set_big_endian_int(jchar, MUS_SAMPLE_TO_INT(buffer[loc])); break; case MUS_LINT: for (; loc < loclim; loc++, jchar += siz_chans) m_set_little_endian_int(jchar, MUS_SAMPLE_TO_INT(buffer[loc])); break; case MUS_BINTN: for (; loc < loclim; loc++, jchar += siz_chans) m_set_big_endian_int(jchar, MUS_SAMPLE_TO_INT(buffer[loc]) << (32 - MUS_SAMPLE_BITS)); break; case MUS_LINTN: for (; loc < loclim; loc++, jchar += siz_chans) m_set_little_endian_int(jchar, MUS_SAMPLE_TO_INT(buffer[loc]) << (32 - MUS_SAMPLE_BITS)); break; case MUS_MULAW: for (; loc < loclim; loc++, jchar += siz_chans) (*jchar) = to_mulaw(MUS_SAMPLE_TO_SHORT(buffer[loc])); break; case MUS_ALAW: for (; loc < loclim; loc++, jchar += siz_chans) (*jchar) = to_alaw(MUS_SAMPLE_TO_SHORT(buffer[loc])); break; case MUS_BYTE: for (; loc < loclim; loc++, jchar += siz_chans) (*((signed char *)jchar)) = MUS_SAMPLE_TO_BYTE(buffer[loc]); break; case MUS_UBYTE: for (; loc < loclim; loc++, jchar += siz_chans) (*jchar) = MUS_SAMPLE_TO_BYTE(buffer[loc]) + 128; break; case MUS_BFLOAT: for (; loc < loclim; loc++, jchar += siz_chans) m_set_big_endian_float(jchar, MUS_SAMPLE_TO_FLOAT(buffer[loc])); break; case MUS_LFLOAT: for (; loc < loclim; loc++, jchar += siz_chans) m_set_little_endian_float(jchar, MUS_SAMPLE_TO_FLOAT(buffer[loc])); break; case MUS_BDOUBLE: for (; loc < loclim; loc++, jchar += siz_chans) m_set_big_endian_double(jchar, MUS_SAMPLE_TO_DOUBLE(buffer[loc])); break; case MUS_LDOUBLE: for (; loc < loclim; loc++, jchar += siz_chans) m_set_little_endian_double(jchar, MUS_SAMPLE_TO_DOUBLE(buffer[loc])); break; case MUS_BFLOAT_UNSCALED: for (; loc < loclim; loc++, jchar += siz_chans) m_set_big_endian_float(jchar, 32768.0 * MUS_SAMPLE_TO_FLOAT(buffer[loc])); break; case MUS_LFLOAT_UNSCALED: for (; loc < loclim; loc++, jchar += siz_chans) m_set_little_endian_float(jchar, 32768.0 * MUS_SAMPLE_TO_FLOAT(buffer[loc])); break; case MUS_BDOUBLE_UNSCALED: for (; loc < loclim; loc++, jchar += siz_chans) m_set_big_endian_double(jchar, 32768.0 * MUS_SAMPLE_TO_DOUBLE(buffer[loc])); break; case MUS_LDOUBLE_UNSCALED: for (; loc < loclim; loc++, jchar += siz_chans) m_set_little_endian_double(jchar, 32768.0 * MUS_SAMPLE_TO_DOUBLE(buffer[loc])); break; case MUS_UBSHORT: for (; loc < loclim; loc++, jchar += siz_chans) m_set_big_endian_unsigned_short(jchar, (unsigned short)(MUS_SAMPLE_TO_SHORT(buffer[loc]) + 32768)); break; case MUS_ULSHORT: for (; loc < loclim; loc++, jchar += siz_chans) m_set_little_endian_unsigned_short(jchar, (unsigned short)(MUS_SAMPLE_TO_SHORT(buffer[loc]) + 32768)); break; case MUS_B24INT: bk = (k * 3); c3 = chans * 3; for (; loc < loclim; loc++, bk += c3) { val = MUS_SAMPLE_TO_INT24(buffer[loc]); charbuf[bk] = (val >> 16); charbuf[bk + 1] = (val >> 8); charbuf[bk + 2] = (val & 0xFF); } break; case MUS_L24INT: bk = (k * 3); c3 = chans * 3; for (; loc < loclim; loc++, bk += c3) { val = MUS_SAMPLE_TO_INT24(buffer[loc]); charbuf[bk + 2] = (val >> 16); charbuf[bk + 1] = (val >> 8); charbuf[bk] = (val & 0xFF); } break; } } if (!to_buffer) { err = checked_write(tfd, charbuf, bytes); if (err == MUS_ERROR) { FREE(charbuf); return(MUS_ERROR); } } } if (!to_buffer) FREE(charbuf); return(MUS_NO_ERROR);}int mus_file_write(int tfd, int beg, int end, int chans, mus_sample_t **bufs){ return(mus_write_1(tfd, beg, end, chans, bufs, NULL, false));}int mus_file_write_file(int tfd, int beg, int end, int chans, mus_sample_t **bufs){ return(mus_write_1(tfd, beg, end, chans, bufs, NULL, false));}int mus_file_write_buffer(int charbuf_data_format, int beg, int end, int chans, mus_sample_t **bufs, char *charbuf, bool clipped){ return(mus_write_1(charbuf_data_format, beg, end, chans, bufs, charbuf, clipped));}/* for CLM */void mus_reset_io_c(void) { io_fd_size = 0; io_fds = NULL; clipping_default = false; prescaler_default = 1.0;}#if (!HAVE_STRDUP)/* this taken from libit-0.7 */char *strdup (const char *str){ char *newstr; newstr = (char *)malloc(strlen(str) + 1); if (newstr) strcpy(newstr, str); return(newstr);}#endif#if (!HAVE_FILENO)/* this is needed by XtAppAddInput */int fileno(FILE *fp){ if (fp == stdout) return(0); else { if (fp == stdin) return(1); } return(2);}#endifstatic int sndlib_strlen(const char *str){ /* strlen(NULL) -> seg fault! */ if ((str) && (*str)) return(strlen(str)); return(0);}char *mus_getcwd(void){ int i, path_max = 0; char *pwd = NULL, *res = NULL;#if HAVE_PATHCONF path_max = pathconf("/", _PC_PATH_MAX);#endif if (path_max < 1024) {#if defined(PATH_MAX) path_max = PATH_MAX;#endif if (path_max < 1024) path_max = 1024; }#if HAVE_GETCWD for (i = path_max;; i *= 2) { if (pwd) FREE(pwd); pwd = (char *)CALLOC(i, sizeof(char)); res = getcwd(pwd, i); if (res) break; /* NULL is returned if failure, but what about success? should I check errno=ERANGE? */ }#else#if HAVE_GETWD pwd = (char *)CALLOC(path_max, sizeof(char)); getwd(pwd);#endif#endif return(pwd);}char *mus_expand_filename(const char *filename){ /* fill out under-specified library pathnames etc */#if defined(MUS_WINDOZE) && (!(defined(__CYGWIN__))) return(strdup(filename));#else char *file_name_buf = NULL; char *tok = NULL, *orig = NULL; int i, j = 0, len = 0; if ((filename) && (*filename)) len = strlen(filename); else return(NULL); if (len == 0) return(NULL); orig = strdup(filename); tok = orig; /* get rid of "//" */ for (i = 0; i < len - 1; i++) { if ((tok[i] == '/') && (tok[i + 1] == '/')) j = i + 1; } if (j > 0) { for (i = 0; j < len; i++, j++) tok[i] = tok[j]; tok[i] ='\0'; } /* get rid of "~/" at start */ if (tok[0] != '/') { char *home = NULL; if ((tok[0] == '~') && (home = getenv("HOME"))) { file_name_buf = (char *)CALLOC(len + sndlib_strlen(home) + 8, sizeof(char)); strcpy(file_name_buf, home); strcat(file_name_buf, ++tok); } else { char *pwd; pwd = mus_getcwd(); file_name_buf = (char *)CALLOC(len + sndlib_strlen(pwd) + 8, sizeof(char)); strcpy(file_name_buf, pwd); FREE(pwd); strcat(file_name_buf, "/"); if (tok[0]) strcat(file_name_buf, tok); } } else { file_name_buf = (char *)CALLOC(len + 8, sizeof(char)); strcpy(file_name_buf, tok); } /* get rid of "/../" and "/./" also "/." at end */ { int slash_at = -1; bool found_one = true; while (found_one) { found_one = false; len = strlen(file_name_buf); for (i = 0; i < len - 3; i++) if (file_name_buf[i] == '/') { if ((file_name_buf[i + 1] == '.') && (file_name_buf[i + 2] == '.') && (file_name_buf[i + 3] == '/')) { i += 4; for (j = slash_at + 1; i < len; i++, j++) file_name_buf[j] = file_name_buf[i]; file_name_buf[j] = '\0'; found_one = true; break; } else { if ((file_name_buf[i + 1] == '.') && (file_name_buf[i + 2] == '/')) { for (j = i + 3, i = i + 1; j < len; i++, j++) file_name_buf[i] = file_name_buf[j]; file_name_buf[i] = '\0'; found_one = true; } else slash_at = i; } } } len = strlen(file_name_buf); if ((len > 1) && (file_name_buf[len - 1] == '.') && (file_name_buf[len - 2] == '/')) file_name_buf[len - 1] = '\0'; } free(orig); return(file_name_buf);#endif}void mus_snprintf(char *buffer, int buffer_len, const char *format, ...){ va_list ap; va_start(ap, format);#if HAVE_VSNPRINTF vsnprintf(buffer, buffer_len, format, ap);#else vsprintf(buffer, format, ap);#endif va_end(ap);}#define MUS_FORMAT_STRING_MAX 1024char *mus_format(const char *format, ...){ /* caller should free result */ char *buf = NULL, *rtn = NULL; va_list ap; buf = (char *)CALLOC(MUS_FORMAT_STRING_MAX, sizeof(char)); va_start(ap, format);#if HAVE_VSNPRINTF vsnprintf(buf, MUS_FORMAT_STRING_MAX, format, ap);#else vsprintf(buf, format, ap);#endif va_end(ap);#if MUS_DEBUGGING rtn = copy_string(buf);#else rtn = strdup(buf);#endif FREE(buf); return(rtn);}Float mus_fclamp(Float lo, Float val, Float hi) { if (val > hi) return(hi); else if (val < lo) return(lo); else return(val);}int mus_iclamp(int lo, int val, int hi) { if (val > hi) return(hi); else if (val < lo) return(lo); else return(val);}off_t mus_oclamp(off_t lo, off_t val, off_t hi) { if (val > hi) return(hi); else if (val < lo) return(lo); else return(val);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -