static Xen g_mus_sound_preload(Xen file) { #define H_mus_sound_preload "(" S_mus_sound_preload " filename): save filename's data in memory (faster opens and so on)." char *str; Xen_check_type(Xen_is_string(file), file, 1, S_mus_sound_preload, "a string"); str = mus_expand_filename(Xen_string_to_C_string(file)); if (str) { int ifd; ifd = mus_sound_open_input(str); if (ifd != MUS_ERROR) { int i, chans; mus_float_t **bufs; mus_long_t framples; chans = mus_sound_chans(str); framples = mus_sound_framples(str) + 8; /* + 8 for readers than wander off the end */ bufs = (mus_float_t **)malloc(chans * sizeof(mus_float_t *)); for (i = 0; i < chans; i++) bufs[i] = (mus_float_t *)malloc(framples * sizeof(mus_float_t)); mus_file_seek_frample(ifd, 0); mus_file_read_file(ifd, 0, chans, framples, bufs); mus_sound_set_saved_data(str, bufs); mus_sound_close_input(ifd); } free(str); } return(file); }
static Xen glmus_sound(const char *caller, mus_long_t (*func)(const char *file), Xen gfilename) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, caller, "a string"); str = mus_expand_filename(Xen_string_to_C_string(gfilename)); result = C_llong_to_Xen_llong((*func)(str)); if (str) free(str); return(result); }
static Xen g_mus_sound_maxamp_exists(Xen file) { #define H_mus_sound_maxamp_exists "(" S_mus_sound_maxamp_exists " filename): " PROC_TRUE " if sound's maxamp data is available \ in the sound cache; if it isn't, a call on " S_mus_sound_maxamp " has to open and read the data to get the maxamp." bool val; char *str = NULL; Xen_check_type(Xen_is_string(file), file, 1, S_mus_sound_maxamp_exists, "a string"); val = mus_sound_maxamp_exists(str = mus_expand_filename(Xen_string_to_C_string(file))); if (str) free(str); return(C_bool_to_Xen_boolean(val)); }
static Xen g_mus_sound_write_date(Xen filename) { char *str = NULL; Xen result; #define H_mus_sound_write_date "(" S_mus_sound_write_date " filename): write date of sound file" Xen_check_type(Xen_is_string(filename), filename, 1, S_mus_sound_write_date, "a string"); str = mus_expand_filename(Xen_string_to_C_string(filename)); result = C_ulong_to_Xen_ulong((unsigned long)mus_sound_write_date(str)); /* actually time_t */ if (str) free(str); return(result); }
static Xen g_mus_sound_set_sample_type(Xen filename, Xen val) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(filename), filename, 1, S_set S_mus_sound_sample_type, "a string"); Xen_check_type(Xen_is_integer(val), val, 2, S_set S_mus_sound_sample_type, "an integer"); str = mus_expand_filename(Xen_string_to_C_string(filename)); result = C_int_to_Xen_integer((int)mus_sound_set_sample_type(str, (mus_sample_t)Xen_integer_to_C_int(val))); if (str) free(str); return(result); }
static Xen g_mus_sound_sample_type(Xen filename) { #define H_mus_sound_sample_type "(" S_mus_sound_sample_type " filename): sample type (e.g. " S_mus_bshort ") of data in sound file" char *str = NULL; Xen result; Xen_check_type(Xen_is_string(filename), filename, 1, S_mus_sound_sample_type, "a string"); str = mus_expand_filename(Xen_string_to_C_string(filename)); result = C_int_to_Xen_integer((int)mus_sound_sample_type(str)); if (str) free(str); return(result); }
static Xen glmus_sound_set(const char *caller, int (*func)(const char *file, mus_long_t newval), Xen gfilename, Xen val) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, caller, "a string"); Xen_check_type(Xen_is_number(val), val, 2, caller, "a number"); str = mus_expand_filename(Xen_string_to_C_string(gfilename)); result = C_llong_to_Xen_llong((*func)(str, Xen_llong_to_C_llong(val))); if (str) free(str); return(result); }
static Xen g_mus_sound_duration(Xen gfilename) { #define H_mus_sound_duration "(" S_mus_sound_duration " filename): duration (in seconds) of sound file" float res; char *str = NULL; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, S_mus_sound_duration, "a string"); res = mus_sound_duration(str = mus_expand_filename(Xen_string_to_C_string(gfilename))); if (str) free(str); return(C_double_to_Xen_real(res)); }
Xen g_mus_expand_filename(Xen file) { #define H_mus_expand_filename "(" S_mus_expand_filename " name): expand 'name' into a canonical or absolute filename, that is, \ one in which all directories in the path are explicit." char *str = NULL; Xen result; Xen_check_type(Xen_is_string(file), file, 1, S_mus_expand_filename, "a string"); str = mus_expand_filename(Xen_string_to_C_string(file)); result = C_string_to_Xen_string(str); if (str) free(str); return(result); }
static Xen g_mus_sound_comment(Xen gfilename) { #define H_mus_sound_comment "(" S_mus_sound_comment " filename): comment (a string) found in sound file's header" char *res = NULL, *str = NULL; Xen newstr; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, S_mus_sound_comment, "a string"); res = mus_sound_comment(str = mus_expand_filename(Xen_string_to_C_string(gfilename))); if (str) free(str); newstr = C_string_to_Xen_string(res); if (res) free(res); return(newstr); }
static Xen g_mus_sound_set_maxamp(Xen file, Xen vals) { int chans; char *filename; Xen_check_type(Xen_is_string(file), file, 1, S_set S_mus_sound_maxamp, "a string"); Xen_check_type(Xen_is_list(vals), vals, 2, S_set S_mus_sound_maxamp, "a list"); filename = mus_expand_filename(Xen_string_to_C_string(file)); chans = mus_sound_chans(filename); /* presumably any actual error here will be trapped via mus-error (raised in mus_header_read via read_sound_file_header), * so chans <= 0 is actually in the header? */ if (chans > 0) { Xen lst; int i, j, len; mus_float_t *mvals; mus_long_t *times; len = Xen_list_length(vals); if (len < (chans * 2)) Xen_wrong_type_arg_error(S_set S_mus_sound_maxamp, 2, vals, "max amp list length must = 2 * chans"); if (len > chans * 2) len = chans * 2; mvals = (mus_float_t *)calloc(chans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); for (i = 0, j = 0, lst = Xen_copy_arg(vals); i < len; i += 2, j++, lst = Xen_cddr(lst)) { times[j] = Xen_llong_to_C_llong(Xen_car(lst)); mvals[j] = Xen_real_to_C_double(Xen_cadr(lst)); } fprintf(stderr, "set in g_mus_sound_set_maxamp\n"); mus_sound_set_maxamps(filename, chans, mvals, times); free(mvals); free(times); if (filename) free(filename); } else { if (filename) free(filename); Xen_error(BAD_HEADER, Xen_list_1(C_string_to_Xen_string(S_set S_mus_sound_maxamp ": chans <= 0"))); } return(vals); }
int mus_sound_forget(const char *name) { int i, len, len2, short_len = 0; bool free_name = false; char *short_name = NULL; if (name == NULL) return(MUS_ERROR); len = strlen(name); if (len > 6) len2 = len - 6; else len2 = len / 2; if (name[0] == '/') { for (i = 0; i < len; i++) if (name[i] == '/') short_name = (char *)(name + i + 1); } else { short_name = mus_expand_filename(name); free_name = true; } if (short_name) short_len = strlen(short_name); if (name) { for (i = 0; i < sound_table_size; i++) if ((sound_table[i]) && (((sound_table[i]->file_name_length == len) && (sound_table[i]->file_name[len2] == name[len2]) && (strcmp(name, sound_table[i]->file_name) == 0)) || ((short_name) && (sound_table[i]->file_name_length == short_len) && (strcmp(short_name, sound_table[i]->file_name) == 0)))) { free_sound_file(sound_table[i]); sound_table[i] = NULL; } } if (free_name) free(short_name); return(MUS_NO_ERROR); }
static void initialize_load_path(void) { /* look for SND_PATH env var, add dirs to %load-path or load_path */ char *path; path = getenv("SND_PATH"); if (path) { /* colon-separated list of directory names, pushed on load-path in reverse order (hopefully = search order) */ int i, len, dirs = 1, curdir = 0, start = 0; char **dirnames; len = strlen(path); for (i = 0; i < len; i++) if (path[i] == ':') dirs++; dirnames = (char **)CALLOC(dirs, sizeof(char *)); for (i = 0; i < len; i++) { if ((path[i] == ':') || (i == len - 1)) { if (i > start) { int j, lim; char *tmp; if (i == (len - 1)) lim = i + 1; else lim = i; tmp = (char *)CALLOC(lim - start + 1, sizeof(char)); for (j = start; j < lim; j++) tmp[j - start] = path[j]; dirnames[curdir++] = mus_expand_filename(tmp); start = i + 1; FREE(tmp); } } } for (i = curdir - 1; i >= 0; i--) { XEN_ADD_TO_LOAD_PATH(dirnames[i]); FREE(dirnames[i]); } FREE(dirnames); } }
static Xen g_mus_sound_loop_info(Xen gfilename) { #define H_mus_sound_loop_info "(" S_mus_sound_loop_info " filename): synth loop info for sound as a list: (start1 \ end1 start2 end2 base-note base-detune mode1 mode2)" int *res; Xen sres = Xen_empty_list; char *str = NULL; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, S_mus_sound_loop_info, "a string"); res = mus_sound_loop_info(str = mus_expand_filename(Xen_string_to_C_string(gfilename))); if (str) free(str); if (res) { sres = Xen_list_8(C_int_to_Xen_integer(res[0]), C_int_to_Xen_integer(res[1]), C_int_to_Xen_integer(res[2]), C_int_to_Xen_integer(res[3]), C_int_to_Xen_integer(res[4]), C_int_to_Xen_integer(res[5]), C_int_to_Xen_integer(res[6]), C_int_to_Xen_integer(res[7])); free(res); } return(sres); }
Xen g_mus_sound_maxamp(Xen file) { #define H_mus_sound_maxamp "(" S_mus_sound_maxamp " filename): maxamps in sound (a list of paired amps (floats) and locations (samples))" int chans; char *filename; Xen res = Xen_empty_list; Xen_check_type(Xen_is_string(file), file, 1, S_mus_sound_maxamp, "a string"); filename = mus_expand_filename(Xen_string_to_C_string(file)); chans = mus_sound_chans(filename); if (chans > 0) { mus_long_t rtn; mus_float_t *vals; mus_long_t *times; vals = (mus_float_t *)calloc(chans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); rtn = mus_sound_maxamps(filename, chans, vals, times); if (rtn != MUS_ERROR) { int i; for (i = chans - 1; i >= 0; i--) res = Xen_cons(C_llong_to_Xen_llong(times[i]), Xen_cons(C_double_to_Xen_real(vals[i]), res)); } free(vals); free(times); if (filename) free(filename); } else { if (filename) free(filename); Xen_error(BAD_HEADER, Xen_list_1(C_string_to_Xen_string(S_mus_sound_maxamp ": chans <= 0"))); } return(res); }
static Xen g_mus_sound_mark_info(Xen gfilename) { #define H_mus_sound_mark_info "(" S_mus_sound_mark_info " filename): aifc header mark info as a list of lists: ((id pos)...)" int *mark_ids, *mark_positions; int marks = 0; Xen sres = Xen_empty_list; char *str = NULL; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, S_mus_sound_mark_info, "a string"); marks = mus_sound_mark_info(str = mus_expand_filename(Xen_string_to_C_string(gfilename)), &mark_ids, &mark_positions); if (str) free(str); if (marks > 0) { int i; for (i = 0; i < marks; i++) sres = Xen_cons(Xen_list_2(C_int_to_Xen_integer(mark_ids[i]), C_int_to_Xen_integer(mark_positions[i])), sres); } return(sres); }
static Xen g_mus_sound_report_cache(Xen file) { #define H_mus_sound_report_cache "(" S_mus_sound_report_cache " (name)): print the current sound \ cache info to the file given or stdout" const char *name; if (!Xen_is_bound(file)) { mus_sound_report_cache(stdout); return(Xen_false); } Xen_check_type(Xen_is_string(file), file, 1, S_mus_sound_report_cache, "a string"); name = Xen_string_to_C_string(file); if (name) { char *str = NULL; str = mus_expand_filename(name); if (str) { FILE *fd; fd = FOPEN(str, "w"); free(str); if (fd) { mus_sound_report_cache(fd); FCLOSE(fd, name); return(file); } } } Xen_error(Xen_make_error_type("cannot-save"), Xen_list_3(C_string_to_Xen_string(S_mus_sound_report_cache ": ~S ~A"), file, C_string_to_Xen_string(STRERROR(errno)))); return(Xen_false); }
int mus_sound_forget(const char *name) { /* apparently here we want to forget either name or the expanded or contracted forms of name -- as many as we find! */ int i, len, len2, short_len = 0; bool free_name = false; char *short_name = NULL; sound_file **sound_table; int sound_table_size, index; char c; if (name == NULL) return(MUS_ERROR); len = strlen(name); if (len > 6) len2 = len - 6; else len2 = len / 2; c = name[len2]; if (name[0] == '/') { for (i = 0; i < len; i++) if (name[i] == '/') short_name = (char *)(name + i + 1); } else { short_name = mus_expand_filename(name); free_name = true; } if (short_name) short_len = strlen(short_name); index = sound_file_hash_index(name, len); sound_table = sound_tables[index]; sound_table_size = sound_table_sizes[index]; for (i = 0; i < sound_table_size; i++) if ((sound_table[i]) && (sound_table[i]->file_name_length == len) && (sound_table[i]->file_name[len2] == c) && (mus_strcmp(name, sound_table[i]->file_name))) { free_sound_file(sound_table[i]); sound_table[i] = NULL; } if (short_name) { if (short_len > 6) len2 = short_len - 6; else len2 = short_len / 2; c = short_name[len2]; index = sound_file_hash_index(short_name, short_len); sound_table = sound_tables[index]; sound_table_size = sound_table_sizes[index]; for (i = 0; i < sound_table_size; i++) if ((sound_table[i]) && (sound_table[i]->file_name_length == short_len) && (sound_table[i]->file_name[len2] == c) && (mus_strcmp(short_name, sound_table[i]->file_name))) { free_sound_file(sound_table[i]); sound_table[i] = NULL; } } if (free_name) free(short_name); return(MUS_NO_ERROR); }