/* Added by Ning Hu May.2001 xsetdir - set current directory of the process */ LVAL xsetdir() { TCHAR ssCurDir[MAX_PATH], szCurDir[MAX_PATH]; int verbose = TRUE; strcpy(ssCurDir, getstring(xlgastring())); if (moreargs()) { verbose = (xlgetarg() != NIL); } xllastarg(); if (ok_to_open(ssCurDir, "r")) { if (SetCurrentDirectory(ssCurDir)) { if (GetCurrentDirectory( sizeof(szCurDir)/sizeof(TCHAR), szCurDir)) { return cvstring(szCurDir); /* create the result string stdputstr("Current Directory: "); stdputstr(szCurDir); stdputstr("\n"); */ } } } if (verbose) stdputstr("Directory Setting Error\n"); /* return nil on error*/ return NIL; }
FILE *osaopen (char *name, char *mode) { FILE *fp = NULL; #ifdef SAFE_NYQUIST if (ok_to_open(name, mode)) #endif fp = fopen (name, mode); return fp; }
FILE *osbopen (char *name, char *mode) { FILE *fp = NULL; char nmode[4]; strcpy (nmode, mode); strcat (nmode, "b"); #ifdef SAFE_NYQUIST if (ok_to_open(name, mode)) #endif fp = fopen (name, mode); return fp; }
LVAL snd_make_read( unsigned char *filename, /* file to read */ time_type offset, /* offset to skip (in seconds) */ time_type t0, /* start time of resulting sound */ long *format, /* AIFF, IRCAM, NeXT, etc. */ long *channels, /* number of channels */ long *mode, /* sample format: PCM, ALAW, etc. */ long *bits, /* BPS: bits per sample */ long *swap, /* swap bytes */ double *srate, /* srate: sample rate */ double *dur, /* duration (in seconds) to read */ long *flags, /* which parameters have been set */ long *byte_offset) /* byte offset in file of first sample */ { register read_susp_type susp; /* srate specified as input parameter */ sample_type scale_factor = 1.0F; sf_count_t frames; double actual_dur; falloc_generic(susp, read_susp_node, "snd_make_read"); memset(&(susp->sf_info), 0, sizeof(SF_INFO)); susp->sf_info.samplerate = ROUND(*srate); susp->sf_info.channels = *channels; switch (*mode) { case SND_MODE_ADPCM: susp->sf_info.format = SF_FORMAT_IMA_ADPCM; break; case SND_MODE_PCM: if (*bits == 8) susp->sf_info.format = SF_FORMAT_PCM_S8; else if (*bits == 16) susp->sf_info.format = SF_FORMAT_PCM_16; else if (*bits == 24) susp->sf_info.format = SF_FORMAT_PCM_24; else if (*bits == 32) susp->sf_info.format = SF_FORMAT_PCM_32; else { susp->sf_info.format = SF_FORMAT_PCM_16; *bits = 16; } break; case SND_MODE_ULAW: susp->sf_info.format = SF_FORMAT_ULAW; break; case SND_MODE_ALAW: susp->sf_info.format = SF_FORMAT_ALAW; break; case SND_MODE_FLOAT: susp->sf_info.format = SF_FORMAT_FLOAT; break; case SND_MODE_UPCM: susp->sf_info.format = SF_FORMAT_PCM_U8; *bits = 8; break; } if (*format == SND_HEAD_RAW) susp->sf_info.format |= SF_FORMAT_RAW; if (*swap) { /* set format to perform a byte swap (change from cpu endian-ness) */ /* write the code so it will only compile if one and only one ENDIAN setting is defined */ #ifdef XL_LITTLE_ENDIAN long format = SF_ENDIAN_BIG; #endif #ifdef XL_BIG_ENDIAN long format = SF_ENDIAN_LITTLE; #endif susp->sf_info.format |= format; } susp->sndfile = NULL; if (ok_to_open((const char *) filename, "rb")) susp->sndfile = sf_open((const char *) filename, SFM_READ, &(susp->sf_info)); if (!susp->sndfile) { char error[240]; sprintf(error, "SND-READ: Cannot open file '%s' because of %s", filename, sf_strerror(susp->sndfile)); xlfail(error); } if (susp->sf_info.channels < 1) { sf_close(susp->sndfile); xlfail("Must specify 1 or more channels"); } /* report samplerate from file, but if user provided a double * as sample rate, don't replace it with an integer. */ if ((susp->sf_info.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) { *srate = susp->sf_info.samplerate; } /* compute dur */ frames = sf_seek(susp->sndfile, 0, SEEK_END); actual_dur = ((double) frames) / *srate; if (offset < 0) offset = 0; /* round offset to an integer frame count */ frames = (sf_count_t) (offset * *srate + 0.5); offset = ((double) frames) / *srate; actual_dur -= offset; if (actual_dur < 0) { sf_close(susp->sndfile); xlfail("SND-READ: offset is beyond end of file"); } if (actual_dur < *dur) *dur = actual_dur; sf_seek(susp->sndfile, frames, SEEK_SET); /* return to read loc in file */ /* initialize susp state */ susp->susp.sr = *srate; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = read_print_tree; /*jlh empty function... */ susp->susp.current = 0; susp->susp.log_stop_cnt = UNKNOWN; /* watch for overflow */ if (*dur * *srate + 0.5 > (unsigned long) 0xFFFFFFFF) { susp->cnt = 0x7FFFFFFF; } else { susp->cnt = ROUND((*dur) * *srate); } switch (susp->sf_info.format & SF_FORMAT_TYPEMASK) { case SF_FORMAT_WAV: *format = SND_HEAD_WAVE; break; case SF_FORMAT_AIFF: *format = SND_HEAD_AIFF; break; case SF_FORMAT_AU: *format = SND_HEAD_NEXT; break; case SF_FORMAT_RAW: *format = SND_HEAD_RAW; break; case SF_FORMAT_PAF: *format = SND_HEAD_PAF; break; case SF_FORMAT_SVX: *format = SND_HEAD_SVX; break; case SF_FORMAT_NIST: *format = SND_HEAD_NIST; break; case SF_FORMAT_VOC: *format = SND_HEAD_VOC; break; case SF_FORMAT_W64: *format = SND_HEAD_W64; break; case SF_FORMAT_MAT4: *format = SND_HEAD_MAT4; break; case SF_FORMAT_MAT5: *format = SND_HEAD_MAT5; break; case SF_FORMAT_PVF: *format = SND_HEAD_PVF; break; case SF_FORMAT_XI: *format = SND_HEAD_XI; break; case SF_FORMAT_HTK: *mode = SND_HEAD_HTK; break; case SF_FORMAT_SDS: *mode = SND_HEAD_SDS; break; case SF_FORMAT_AVR: *mode = SND_HEAD_AVR; break; case SF_FORMAT_WAVEX: *format = SND_HEAD_WAVE; break; case SF_FORMAT_SD2: *format = SND_HEAD_SD2; break; case SF_FORMAT_FLAC: *format = SND_HEAD_FLAC; break; case SF_FORMAT_CAF: *format = SND_HEAD_CAF; break; case SF_FORMAT_OGG: *format = SND_HEAD_OGG; break; default: *format = SND_HEAD_NONE; break; } *channels = susp->sf_info.channels; switch (susp->sf_info.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_S8: *bits = 8; *mode = SND_MODE_PCM; break; case SF_FORMAT_PCM_16: *bits = 16; *mode = SND_MODE_PCM; break; case SF_FORMAT_PCM_24: *bits = 24; *mode = SND_MODE_PCM; break; case SF_FORMAT_PCM_32: *bits = 32; *mode = SND_MODE_PCM; break; case SF_FORMAT_PCM_U8: *bits = 8; *mode = SND_MODE_UPCM; break; case SF_FORMAT_FLOAT: *bits = 32; *mode = SND_MODE_FLOAT; break; case SF_FORMAT_DOUBLE: *bits = 64; *mode = SND_MODE_DOUBLE; break; case SF_FORMAT_ULAW: *bits = 8; *mode = SND_MODE_ULAW; break; case SF_FORMAT_ALAW: *bits = 8; *mode = SND_MODE_ALAW; break; case SF_FORMAT_IMA_ADPCM: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_MS_ADPCM: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_GSM610: *bits = 16; *mode = SND_MODE_GSM610; break; case SF_FORMAT_VOX_ADPCM: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_G721_32: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_G723_24: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_G723_40: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_DWVW_12: *bits = 12; *mode = SND_MODE_DWVW; break; case SF_FORMAT_DWVW_16: *bits = 16; *mode = SND_MODE_DWVW; break; case SF_FORMAT_DWVW_24: *bits = 24; *mode = SND_MODE_DWVW; break; case SF_FORMAT_DWVW_N: *bits = 32; *mode = SND_MODE_DWVW; break; case SF_FORMAT_DPCM_8: *bits = 8; *mode = SND_MODE_DPCM; break; case SF_FORMAT_DPCM_16: *bits = 16; *mode = SND_MODE_DPCM; break; default: *mode = SND_MODE_UNKNOWN; break; } sndread_file_open_count++; #ifdef MACINTOSH if (sndread_file_open_count > 24) { nyquist_printf("Warning: more than 24 sound files are now open\n"); } #endif /* report info back to caller */ if ((susp->sf_info.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) { *flags = SND_HEAD_CHANNELS | SND_HEAD_MODE | SND_HEAD_BITS | SND_HEAD_SRATE | SND_HEAD_LEN | SND_HEAD_TYPE; } if (susp->sf_info.channels == 1) { susp->susp.fetch = read__fetch; susp->susp.free = read_free; susp->susp.name = "read"; return cvsound(sound_create((snd_susp_type)susp, t0, *srate, scale_factor)); } else { susp->susp.fetch = multiread_fetch; susp->susp.free = multiread_free; susp->susp.name = "multiread"; return multiread_create(susp); } }
double sound_overwrite( LVAL snd_expr, long n, unsigned char *filename, double offset_secs, long format, long mode, long bits, long swap, double *duration) { LVAL result; // the SOUND to be evaluated SF_INFO sf_info; // info about the sound file double max_sample; // return value long ntotal; // how many samples were overwritten /* long flags; */ // first check if sound file exists, do not create new file FILE *file = NULL; if (ok_to_open((char *) filename, "rb")) file = fopen((char *) filename, "rb"); // if not then fail if (!file) { *duration = 0; return 0.0; } else { fclose(file); } memset(&sf_info, 0, sizeof(sf_info)); sf_info.format = lookup_format(format, mode, bits, swap); result = xleval(snd_expr); /* BE CAREFUL - DO NOT ALLOW GC TO RUN WHILE RESULT IS UNPROTECTED */ if (vectorp(result)) { SNDFILE *sndfile; // opened sound file float *buf; // buffer for samples read in from sound file /* make sure all elements are of type a_sound */ long i = getsize(result); long channels = i; while (i > 0) { i--; if (!exttypep(getelement(result, i), a_sound)) { xlerror("sound_save: array has non-sound element", result); } } sndfile = open_for_write(filename, SFM_RDWR, format, &sf_info, channels, ROUND(getsound(getelement(result, 0))->sr), offset_secs, &buf); max_sample = sound_save_array(result, n, &sf_info, sndfile, buf, &ntotal, NULL); *duration = ntotal / (double) sf_info.samplerate; free(buf); sf_close(sndfile); } else if (exttypep(result, a_sound)) { SNDFILE *sndfile; // opened sound file float *buf; // buffer for samples read in from sound file sndfile = open_for_write(filename, SFM_RDWR, format, &sf_info, 1, ROUND(getsound(result)->sr), offset_secs, &buf); max_sample = sound_save_sound(result, n, &sf_info, sndfile, buf, &ntotal, NULL); *duration = ntotal / (double) sf_info.samplerate; free(buf); sf_close(sndfile); } else { xlerror("sound_save: expression did not return a sound", result); max_sample = 0.0; } return max_sample; }
/* * if the format is RAW, then fill in sf_info according to * sound sample rate and channels. Otherwise, open the file * and see if the sample rate and channele match. */ SNDFILE *open_for_write(unsigned char *filename, long direction, long format, SF_INFO *sf_info, int channels, long srate, double offset, float **buf) /* channels and srate are based on the sound we're writing to the file */ { SNDFILE *sndfile; sf_count_t frames; // frame count passed into sf_seek char error[140]; // error messages are formatted here sf_count_t rslt; // frame count returned from sf_seek if (format == SND_HEAD_RAW) { sf_info->channels = channels; sf_info->samplerate = srate; } else { sf_info->format = 0; } sndfile = NULL; if (ok_to_open((char *) filename, "w")) sndfile = sf_open((const char *) filename, direction, sf_info); if (!sndfile) { snprintf(error, sizeof(error), "snd_overwrite: cannot open file %s", filename); xlabort(error); } /* use proper scale factor: 8000 vs 7FFF */ sf_command(sndfile, SFC_SET_CLIPPING, NULL, SF_TRUE); frames = round(offset * sf_info->samplerate); rslt = sf_seek(sndfile, frames, SEEK_SET); if (rslt < 0) { snprintf(error, sizeof(error), "snd_overwrite: cannot seek to frame %lld of %s", frames, filename); xlabort(error); } if (sf_info->channels != channels) { snprintf(error, sizeof(error), "%s%d%s%d%s", "snd_overwrite: number of channels in sound (", channels, ") does not match\n number of channels in file (", sf_info->channels, ")"); sf_close(sndfile); xlabort(error); } if (sf_info->samplerate != srate) { snprintf(error, sizeof(error), "%s%ld%s%d%s", "snd_overwrite: sample rate in sound (", srate, ") does not match\n sample rate in file (", sf_info->samplerate, ")"); sf_close(sndfile); xlabort(error); } if ((*buf = (float *) malloc(max_sample_block_len * channels * sizeof(float))) == NULL) { xlabort("snd_overwrite: couldn't allocate memory"); } return sndfile; }
double sound_save( LVAL snd_expr, long n, unsigned char *filename, long format, long mode, long bits, long swap, double *sr, long *nchans, double *duration, LVAL play) { LVAL result; float *buf; long ntotal; double max_sample; SNDFILE *sndfile = NULL; SF_INFO sf_info; PaStream *audio_stream = NULL; if (SAFE_NYQUIST) play = FALSE; gc(); memset(&sf_info, 0, sizeof(sf_info)); sf_info.format = lookup_format(format, mode, bits, swap); result = xleval(snd_expr); /* BE CAREFUL - DO NOT ALLOW GC TO RUN WHILE RESULT IS UNPROTECTED */ if (vectorp(result)) { /* make sure all elements are of type a_sound */ long i = getsize(result); *nchans = sf_info.channels = i; while (i > 0) { i--; if (!exttypep(getelement(result, i), a_sound)) { xlerror("sound_save: array has non-sound element", result); } } /* assume all are the same: */ *sr = sf_info.samplerate = ROUND(getsound(getelement(result, 0))->sr); /* note: if filename is "", then don't write file; therefore, * write the file if (filename[0]) */ if (filename[0]) { sndfile = NULL; if (ok_to_open((char *) filename, "wb")) sndfile = sf_open((char *) filename, SFM_WRITE, &sf_info); if (sndfile) { /* use proper scale factor: 8000 vs 7FFF */ sf_command(sndfile, SFC_SET_CLIPPING, NULL, SF_TRUE); } } if (play) play = prepare_audio(play, &sf_info, &audio_stream); if ((buf = (float *) malloc(max_sample_block_len * sf_info.channels * sizeof(float))) == NULL) { xlabort("snd_save -- couldn't allocate memory"); } max_sample = sound_save_array(result, n, &sf_info, sndfile, buf, &ntotal, audio_stream); *duration = ntotal / *sr; if (sndfile) sf_close(sndfile); if (play != NIL) finish_audio(audio_stream); } else if (exttypep(result, a_sound)) { *nchans = sf_info.channels = 1; sf_info.samplerate = ROUND((getsound(result))->sr); *sr = sf_info.samplerate; if (filename[0]) { sndfile = NULL; if (ok_to_open((char *) filename, "wb")) { sndfile = sf_open((char *) filename, SFM_WRITE, &sf_info); if (sndfile) { /* use proper scale factor: 8000 vs 7FFF */ sf_command(sndfile, SFC_SET_CLIPPING, NULL, SF_TRUE); } else { char error[240]; sprintf(error, "snd_save -- %s", sf_error_number(sf_error(sndfile))); xlabort(error); } } else { xlabort("snd_save -- write not permitted by -W option"); } } if (play) play = prepare_audio(play, &sf_info, &audio_stream); if ((buf = (float *) malloc(max_sample_block_len * sizeof(float))) == NULL) { xlabort("snd_save -- couldn't allocate memory"); } max_sample = sound_save_sound(result, n, &sf_info, sndfile, buf, &ntotal, audio_stream); *duration = ntotal / *sr; if (sndfile) sf_close(sndfile); if (play != NIL) finish_audio(audio_stream); } else { xlerror("sound_save: expression did not return a sound", result); max_sample = 0.0; } free(buf); return max_sample; }