void sfopenout(CSOUND *csound) /* init for sound out */ { /* (not called if nosound) */ OPARMS *O = csound->oparms; char *s, *fName, *fullName; SF_INFO sfinfo; int osfd = 1; /* stdout */ alloc_globals(csound); if (O->outfilename == NULL) { switch (O->filetyp) { case TYP_WAV: case TYP_W64: case TYP_WAVEX: case TYP_RF64: O->outfilename = "test.wav"; break; case TYP_AIFF: O->outfilename = "test.aif"; break; case TYP_AU: O->outfilename = "test.au"; break; case TYP_PAF: O->outfilename = "test.paf"; break; case TYP_SVX: O->outfilename = "test.svx"; break; case TYP_NIST: O->outfilename = "test.sph"; break; case TYP_VOC: O->outfilename = "test.voc"; break; /* case TYP_IRCAM: */ /* O->outfilename = ""; */ /* break; */ /* case TYP_MAT4: */ /* O->outfilename = ""; */ /* break; */ /* case TYP_MAT5: */ /* O->outfilename = ""; */ /* break; */ /* case TYP_PVF: */ /* O->outfilename = ""; */ /* break; */ case TYP_XI: O->outfilename = "test.xi"; break; /* case TYP_HTK: */ /* O->outfilename = ""; */ /* break; */ /* case TYP_SDS: */ /* O->outfilename = "test.sds"; */ /* break; */ case TYP_AVR: O->outfilename = "test.avr"; break; case TYP_SD2: O->outfilename = "test.sd2"; break; case TYP_FLAC: O->outfilename = "test.flac"; break; case TYP_CAF: O->outfilename = "test.caf"; break; case TYP_OGG: O->outfilename = "test.ogg"; break; /* case TYP_MPC2K: */ /* O->outfilename = ""; */ /* break; */ default: O->outfilename = "test"; break; } } STA(sfoutname) = fName = O->outfilename; if (strcmp(fName, "stdout") == 0) { STA(pipdevout) = 1; } #ifdef PIPES else if (fName[0] == '|') { STA(pout) = _popen(fName+1, "w"); osfd = fileno(STA(pout)); STA(pipdevout) = 1; if (O->filetyp == TYP_AIFF || O->filetyp == TYP_WAV) { char fmt_name[6]; if (O->sfsampsize == 8) { strcpy(fmt_name, "AU"); O->filetyp = TYP_AU; } else { strcpy(fmt_name, "IRCAM"); O->filetyp = TYP_IRCAM; } csound->Message(csound, Str("Output file type changed to %s " "for use in pipe\n"), fmt_name); } } #endif else { csRtAudioParams parm; /* check for real time audio output, and get device name/number */ parm.devNum = check_rtaudio_name(fName, &(parm.devName), 1); if (parm.devNum >= 0) { /* set device parameters */ parm.bufSamp_SW = (unsigned int) O->outbufsamps / csound->nchnls; parm.bufSamp_HW = O->oMaxLag; parm.nChannels = csound->nchnls; parm.sampleFormat = O->outformat; parm.sampleRate = (float) csound->esr; csound->spoutran = spoutsf; /* open devaudio for output */ if (UNLIKELY(csound->playopen_callback(csound, &parm) != 0)) csoundDie(csound, Str("Failed to initialise real time audio output")); /* & redirect audio puts */ csound->audtran = csound->rtplay_callback; STA(outbufrem) = parm.bufSamp_SW * parm.nChannels; STA(pipdevout) = 2; /* no backward seeks ! */ if (O->realtime == 1) /* set realtime priority mode */ csound->realtime_audio_flag = 1; goto outset; /* no header needed */ } else if (strcmp(fName, "null") == 0) { STA(outfile) = NULL; if (csound->dither_output && csound->oparms->outformat!=AE_FLOAT && csound->oparms->outformat!=AE_DOUBLE) { if (csound->oparms->outformat==AE_SHORT) if (csound->dither_output==1) csound->audtran = writesf_dither_16; else csound->audtran = writesf_dither_u16; else if (csound->oparms->outformat==AE_CHAR) if (csound->dither_output==1) csound->audtran = writesf_dither_8; else csound->audtran = writesf_dither_u8; else csound->audtran = writesf; } else csound->audtran = writesf; goto outset; } } /* set format parameters */ memset(&sfinfo, 0, sizeof(SF_INFO)); //sfinfo.frames = 0; sfinfo.samplerate = (int) MYFLT2LRND(csound->esr); sfinfo.channels = csound->nchnls; sfinfo.format = TYPE2SF(O->filetyp) | FORMAT2SF(O->outformat); /* open file */ if (STA(pipdevout)) { STA(outfile) = sf_open_fd(osfd, SFM_WRITE, &sfinfo, 0); #ifdef PIPES if (STA(outfile) == NULL) { char fmt_name[6]; if (O->sfsampsize == 8) { if (UNLIKELY(O->filetyp == TYP_AU)) csoundDie(csound, Str("sfinit: cannot open fd %d\n%s"), osfd, Str(sf_strerror(NULL))); strcpy(fmt_name, "AU"); O->filetyp = TYP_AU; } else { if (UNLIKELY(O->filetyp == TYP_IRCAM)) csoundDie(csound, Str("sfinit: cannot open fd %d\n%s"), osfd, Str(sf_strerror(NULL))); strcpy(fmt_name, "IRCAM"); O->filetyp = TYP_IRCAM; } csound->Message(csound, Str("Output file type changed to %s " "for use in pipe\n"), fmt_name); sfinfo.format = TYPE2SF(O->filetyp) | FORMAT2SF(O->outformat); STA(outfile) = sf_open_fd(osfd, SFM_WRITE, &sfinfo, 0); } #endif if (UNLIKELY(STA(outfile) == NULL)) csoundDie(csound, Str("sfinit: cannot open fd %d\n%s"), osfd, Str(sf_strerror(NULL))); sf_command(STA(outfile), SFC_SET_VBR_ENCODING_QUALITY, &O->quality, sizeof(double)); } else { fullName = csoundFindOutputFile(csound, fName, "SFDIR"); if (UNLIKELY(fullName == NULL)) csoundDie(csound, Str("sfinit: cannot open %s"), fName); STA(sfoutname) = fullName; STA(outfile) = sf_open(fullName, SFM_WRITE, &sfinfo); if (UNLIKELY(STA(outfile) == NULL)) csoundDie(csound, Str("sfinit: cannot open %s\n%s"), fullName, sf_strerror (NULL)); sf_command(STA(outfile), SFC_SET_VBR_ENCODING_QUALITY, &O->quality, sizeof(double)); /* only notify the host if we opened a real file, not stdout or a pipe */ csoundNotifyFileOpened(csound, fullName, type2csfiletype(O->filetyp, O->outformat), 1, 0); } /* IV - Feb 22 2005: clip integer formats */ if (O->outformat != AE_FLOAT && O->outformat != AE_DOUBLE) sf_command(STA(outfile), SFC_SET_CLIPPING, NULL, SF_TRUE); sf_command(STA(outfile), SFC_SET_ADD_PEAK_CHUNK, NULL, (csound->peakchunks ? SF_TRUE : SF_FALSE)); #ifdef SOME_FINE_DAY if (csound->dither_output) { /* This may not be written yet!! */ SF_DITHER_INFO ditherInfo; memset(&ditherInfo, 0, sizeof(SF_DITHER_INFO)); ditherInfo.type = SFD_TRIANGULAR_PDF | SFD_DEFAULT_LEVEL; ditherInfo.level = 1.0; ditherInfo.name = (char*) NULL; sf_command(STA(outfile), SFC_SET_DITHER_ON_WRITE, &ditherInfo, sizeof(SF_DITHER_INFO)); } #endif if (!(O->outformat == AE_FLOAT || O->outformat == AE_DOUBLE) || (O->filetyp == TYP_WAV || O->filetyp == TYP_AIFF || O->filetyp == TYP_W64)) csound->spoutran = spoutsf; /* accumulate output */ else csound->spoutran = spoutsf_noscale; if (csound->dither_output && csound->oparms->outformat!=AE_FLOAT && csound->oparms->outformat!=AE_DOUBLE) { if (csound->oparms->outformat==AE_SHORT) csound->audtran = writesf_dither_16; else if (csound->oparms->outformat==AE_CHAR) csound->audtran = writesf_dither_8; else csound->audtran = writesf; } else csound->audtran = writesf; /* Write any tags. */ if ((s = csound->SF_id_title) != NULL && *s != '\0') sf_set_string(STA(outfile), SF_STR_TITLE, s); if ((s = csound->SF_csd_licence) == NULL || *s == '\0') s = csound->SF_id_copyright; if (s != NULL && *s != '\0') sf_set_string(STA(outfile), SF_STR_COPYRIGHT, s); else if (csound->SF_id_scopyright>=0) { char buff[256]; time_t tt = time(NULL); strftime(buff, 256, "Copyright %Y: ", gmtime(&tt)); strncat(buff,copyrightcode(csound->SF_id_scopyright), 255); buff[255] = '\0'; sf_set_string(STA(outfile), SF_STR_COPYRIGHT, buff); } if ((s = csound->SF_id_software) != NULL && *s != '\0') sf_set_string(STA(outfile), SF_STR_SOFTWARE, s); if ((s = csound->SF_id_artist) != NULL && *s != '\0') sf_set_string(STA(outfile), SF_STR_ARTIST, s); if ((s = csound->SF_id_comment) != NULL && *s != '\0') sf_set_string(STA(outfile), SF_STR_COMMENT, s); if ((s = csound->SF_id_date) != NULL && *s != '\0') sf_set_string(STA(outfile), SF_STR_DATE, s); /* file is now open */ STA(osfopen) = 1; outset: O->sfsampsize = (int) sfsampsize(FORMAT2SF(O->outformat)); /* calc outbuf size & alloc bufspace */ STA(outbufsiz) = O->outbufsamps * sizeof(MYFLT); STA(outbufp) = STA(outbuf) = csound->Malloc(csound, STA(outbufsiz)); if (STA(pipdevout) == 2) csound->Message(csound, Str("writing %d sample blks of %lu-bit floats to %s\n"), O->outbufsamps, (unsigned long) sizeof(MYFLT)*8, STA(sfoutname)); else { csound->Message(csound, Str("writing %d-byte blks of %s to %s"), O->outbufsamps * O->sfsampsize, getstrformat(O->outformat), STA(sfoutname)); if (O->sfheader == 0) csound->Message(csound, Str(" (raw)\n")); else csound->Message(csound, " (%s)\n", type2string(O->filetyp)); } STA(osfopen) = 1; STA(outbufrem) = O->outbufsamps; }
/* type should be one of libsndfile's format values. */ int sftype2csfiletype(int type) { /* mask out the endian-ness bits */ int typemod = type & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK); return type2csfiletype(SF2TYPE(typemod), SF2FORMAT(typemod)); }