Example #1
0
void sfopenin(CSOUND *csound)           /* init for continuous soundin */
{
    OPARMS  *O = csound->oparms;
    char    *sfname, *fullName;
    SF_INFO sfinfo;
    int     fileType = (int) TYP_RAW;
    int     isfd = 0;   /* stdin */

    alloc_globals(csound);
    STA(inbufrem) = (uint32) 0;    /* start with empty buffer */
    sfname = O->infilename;
    if (UNLIKELY(sfname == NULL || sfname[0] == '\0'))
      csound->Die(csound, Str("error: no input file name"));

    if (strcmp(sfname, "stdin") == 0) {
      STA(pipdevin) = 1;
    }
#ifdef PIPES
    else if (sfname[0] == '|') {
      STA(pin) = _popen(sfname + 1, "r");
      isfd = fileno(STA(pin));
      STA(pipdevin) = 1;
    }
#endif
    else {
      csRtAudioParams   parm;
      /* check for real time audio input, and get device name/number */
      parm.devNum = check_rtaudio_name(sfname, &(parm.devName), 0);
      if (parm.devNum >= 0) {
        /* set device parameters */
        parm.bufSamp_SW   =
          (unsigned int) O->inbufsamps / (unsigned int) csound->inchnls;
        parm.bufSamp_HW   = O->oMaxLag;
        parm.nChannels    = csound->inchnls;
        parm.sampleFormat = O->informat;
        parm.sampleRate   = (float) csound->esr;
        /* open devaudio for input */
        if (UNLIKELY(csound->recopen_callback(csound, &parm) != 0))
          csoundDie(csound, Str("Failed to initialise real time audio input"));
        /*  & redirect audio gets  */
        csound->audrecv = csound->rtrecord_callback;
        STA(pipdevin) = 2;       /* no backward seeks !     */
        goto inset;             /* no header processing    */
      }
    }
    /* open file */
    memset(&sfinfo, 0, sizeof(SF_INFO));
    if (STA(pipdevin)) {
      STA(infile) = sf_open_fd(isfd, SFM_READ, &sfinfo, 0);
      if (UNLIKELY(STA(infile) == NULL)) {
        /* open failed: possibly raw file, but cannot seek back to try again */
        const char *sfError = Str(sf_strerror(NULL));
        csoundDie(csound, Str("isfinit: cannot open %s -- %s"), sfname, sfError);
      }
    }
    else {
      fullName = csoundFindInputFile(csound, sfname, "SFDIR;SSDIR");
      if (UNLIKELY(fullName == NULL))                     /* if not found */
        csoundDie(csound, Str("isfinit: cannot open %s"), sfname);
      STA(infile) = sf_open(fullName, SFM_READ, &sfinfo);
      if (STA(infile) == NULL) {
        /* open failed: maybe raw file ? */
        memset(&sfinfo, 0, sizeof(SF_INFO));
        sfinfo.samplerate = (int) MYFLT2LRND(csound->esr);
        sfinfo.channels = csound->nchnls;
        /* FIXME: assumes input sample format is same as output */
        sfinfo.format = TYPE2SF(TYP_RAW) | FORMAT2SF(O->outformat);
        STA(infile) = sf_open(fullName, SFM_READ, &sfinfo);  /* try again */
      }
      if (UNLIKELY(STA(infile) == NULL)) {
        const char *sfError = Str(sf_strerror(NULL));
        csoundDie(csound, Str("isfinit: cannot open %s -- %s"), fullName, sfError);
      }
      /* only notify the host if we opened a real file, not stdin or a pipe */
      csoundNotifyFileOpened(csound, fullName,
                              sftype2csfiletype(sfinfo.format), 0, 0);
      sfname = fullName;
    }
    /* chk the hdr codes  */
    if (sfinfo.samplerate != (int) MYFLT2LRND(csound->esr)) {
      csound->Warning(csound, Str("audio_in %s has sr = %d, orch sr = %d"),
                              sfname, (int) sfinfo.samplerate,
                              (int) MYFLT2LRND(csound->esr));
    }
    if (sfinfo.channels != csound->inchnls) {
      csound->Warning(csound, Str("audio_in %s has %d chnls, orch %d chnls_i"),
                              sfname, (int) sfinfo.channels, csound->inchnls);
    }
    /* Do we care about the format?  Can assume float?? */
    O->informat = SF2FORMAT(sfinfo.format);
    fileType = (int) SF2TYPE(sfinfo.format);
    csound->audrecv = readsf;           /* will use standard audio gets  */
    if ((O->informat == AE_FLOAT || O->informat == AE_DOUBLE) &&
        !(fileType == TYP_WAV || fileType == TYP_AIFF || fileType == TYP_W64)) {
      /* do not scale "raw" floating point files */
      csound->spinrecv = sndfilein_noscale;
    }

 inset:
    /* calc inbufsize reqd */
    STA(inbufsiz) = (unsigned) (O->inbufsamps * sizeof(MYFLT));
    STA(inbuf) = (MYFLT*) csound->Calloc(csound,
                                         STA(inbufsiz)); /* alloc inbuf space */
    if (STA(pipdevout) == 2)
      csound->Message(csound,
                      Str("reading %d sample blks of %lu-bit floats from %s\n"),
                      O->inbufsamps * O->sfsampsize,
                      (unsigned long) sizeof(MYFLT)*8, sfname);
    else {
      csound->Message(csound,
                      Str("reading %d-byte blks of %s from %s (%s)\n"),
                      O->inbufsamps * (int) sfsampsize(FORMAT2SF(O->informat)),
                      getstrformat(O->informat), sfname, type2string(fileType));
    }
    STA(isfopen) = 1;
}
Example #2
0
/* 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));
}
Example #3
0
SNDMEMFILE *csoundLoadSoundFile(CSOUND *csound, const char *fileName, void *sfi)
{
    SF_INFO       *sfinfo = sfi;
    SNDFILE       *sf;
    void          *fd;
    SNDMEMFILE    *p = NULL;
    SF_INFO       tmp;


    if (UNLIKELY(fileName == NULL || fileName[0] == '\0'))
      return NULL;

    /* check if file is already loaded */
    if (csound->sndmemfiles != NULL) {
      p = cs_hash_table_get(csound, csound->sndmemfiles, (char*)fileName);
    }
    else {
      csound->sndmemfiles = cs_hash_table_create(csound);
    }

    if (p != NULL) {
      /* if file was loaded earlier: */
      if (sfinfo != NULL) {
        memset(sfinfo, 0, sizeof(SF_INFO));
        sfinfo->frames = (sf_count_t) p->nFrames;
        sfinfo->samplerate = ((int) p->sampleRate + 0.5);
        sfinfo->channels = p->nChannels;
        sfinfo->format = FORMAT2SF(p->sampleFormat) | TYPE2SF(p->fileType);
      }
      return p;
    }
    /* open file */
    if (sfinfo == NULL) {
      memset(&tmp, 0, sizeof(SF_INFO));
      sfinfo = &tmp;
    }
    fd = csound->FileOpen2(csound, &sf, CSFILE_SND_R, fileName, sfinfo,
                            "SFDIR;SSDIR", CSFTYPE_UNKNOWN_AUDIO, 0);
    if (UNLIKELY(fd == NULL)) {
      csound->ErrorMsg(csound,
                       Str("csoundLoadSoundFile(): failed to open '%s'"),
                       fileName);
      return NULL;
    }
    p = (SNDMEMFILE*)
            csound->Malloc(csound, sizeof(SNDMEMFILE)
                           + (size_t)  sfinfo->frames * sizeof(float));
    /* set parameters */
    p->name = (char*) csound->Malloc(csound, strlen(fileName) + 1);
    strcpy(p->name, fileName);
    p->fullName = (char*) csound->Malloc(csound,
                                         strlen(csound->GetFileName(fd)) + 1);
    strcpy(p->fullName, csound->GetFileName(fd));
    p->sampleRate = (double) sfinfo->samplerate;
    p->nFrames = (size_t) sfinfo->frames;
    p->nChannels = sfinfo->channels;
    p->sampleFormat = SF2FORMAT(sfinfo->format);
    p->fileType = SF2TYPE(sfinfo->format);
    /* set defaults for sampler information */
    p->loopMode = 0;
    p->startOffs = 0.0;
    p->loopStart = 0.0;
    p->loopEnd = 0.0;
    p->baseFreq = 1.0;
    p->scaleFac = 1.0;
    {
      SF_INSTRUMENT lpd;
      if (sf_command(sf, SFC_GET_INSTRUMENT, &lpd, sizeof(SF_INSTRUMENT))
          != 0) {
        if (lpd.loop_count > 0 && lpd.loops[0].mode != SF_LOOP_NONE) {
          /* set loop mode and loop points */
          p->loopMode = (lpd.loops[0].mode == SF_LOOP_FORWARD ?
                         2 : (lpd.loops[0].mode == SF_LOOP_BACKWARD ? 3 : 4));
          p->loopStart = (double) lpd.loops[0].start;
          p->loopEnd = (double) lpd.loops[0].end;
        }
        else {
          /* loop mode: off */
          p->loopMode = 1;
        }
        p->baseFreq = pow(2.0, (double) (((int) lpd.basenote - 69) * 100
                                         + (int) lpd.detune) / 1200.0) * 440.0;
        p->scaleFac = pow(10.0, (double) lpd.gain * 0.05);
      }
    }
    if ((size_t) sf_readf_float(sf, &(p->data[0]), (sf_count_t) p->nFrames)
        != p->nFrames) {
      csound->FileClose(csound, fd);
      csound->Free(csound, p->name);
      csound->Free(csound, p->fullName);
      csound->Free(csound, p);
      csound->ErrorMsg(csound, Str("csoundLoadSoundFile(): error reading '%s'"),
                               fileName);
      return NULL;
    }
    p->data[p->nFrames] = 0.0f;
    csound->FileClose(csound, fd);
    csound->Message(csound, Str("File '%s' (sr = %d Hz, %d channel(s), %lu "
                                "sample frames) loaded into memory\n"),
                            p->fullName, (int) sfinfo->samplerate,
                            (int) sfinfo->channels,
                            (uint32) sfinfo->frames);

    /* link into database */
    cs_hash_table_put(csound, csound->sndmemfiles, (char*)fileName, p);

    /* return with pointer to file structure */
    return p;
}
Example #4
0
void *sndgetset(CSOUND *csound, void *p_)
{
    SOUNDIN *p = (SOUNDIN*) p_;
    int     n;
    int     framesinbuf, skipframes;
    char    *sfname;
    SF_INFO sfinfo;

    sfname = &(p->sfname[0]);
    /* IV - Feb 26 2005: should initialise sfinfo structure */
    memset(&sfinfo, 0, sizeof(SF_INFO));
    sfinfo.format = (p->format ?        /* store default sample format, */
                     ((int) FORMAT2SF(p->format) | SF_FORMAT_RAW) : 0);
    sfinfo.channels = 1;                /* number of channels, */
    if (p->analonly)                    /* and sample rate */
      sfinfo.samplerate = (int) p->sr;
    else
      sfinfo.samplerate = (int) ((double) csound->esr + 0.5);
    if (sfinfo.samplerate < 1)
      sfinfo.samplerate = (int) ((double) DFLT_SR + 0.5);
    /* open with full dir paths */
    p->fd = csound->FileOpen2(csound, &(p->sinfd), CSFILE_SND_R,
                                     sfname, &sfinfo, "SFDIR;SSDIR",
                                     CSFTYPE_UNKNOWN_AUDIO, 0);
    if (UNLIKELY(p->fd == NULL)) {
      csound->ErrorMsg(csound, Str("soundin cannot open %s"), sfname);
      goto err_return;
    }
    /* & record fullpath filnam */
    sfname = csound->GetFileName(p->fd);

    /* copy type from headata */
    p->format = SF2FORMAT(sfinfo.format);
    p->sampframsiz = (int) sfsampsize(sfinfo.format) * (int) sfinfo.channels;
    p->nchanls = sfinfo.channels;
    framesinbuf = (int) SNDINBUFSIZ / (int) p->nchanls;
    p->bufsmps = framesinbuf * p->nchanls;
    p->endfile = 0;
    p->filetyp = SF2TYPE(sfinfo.format);
    if (p->analonly) {                              /* anal: if sr param val */
      if (p->sr != 0 && p->sr != sfinfo.samplerate) {   /*   use it          */
        csound->Warning(csound, Str("-s %d overriding soundfile sr %d"),
                                (int) p->sr, (int) sfinfo.samplerate);
        sfinfo.samplerate = p->sr;
      }
    }
    else if (sfinfo.samplerate != (int) ((double) csound->esr + 0.5)) {
      csound->Warning(csound,                       /* non-anal:  cmp w. esr */
                      "%s sr = %d, orch sr = %7.1f",
                      sfname, (int) sfinfo.samplerate, csound->esr);
    }
    if (UNLIKELY(p->channel != ALLCHNLS && p->channel > sfinfo.channels)) {
      csound->ErrorMsg(csound, Str("error: req chan %d, file %s has only %d"),
                               (int) p->channel, sfname, (int) sfinfo.channels);
      goto err_return;
    }
    p->sr = (int) sfinfo.samplerate;
    if (csound->oparms_.msglevel & 3) {
      csound->Message(csound, Str("audio sr = %d, "), (int) p->sr);
      switch (p->nchanls) {
        case 1: csound->Message(csound, Str("monaural")); break;
        case 2: csound->Message(csound, Str("stereo"));   break;
        case 4: csound->Message(csound, Str("quad"));     break;
        case 6: csound->Message(csound, Str("hex"));      break;
        case 8: csound->Message(csound, Str("oct"));      break;
        default: csound->Message(csound, Str("%d-channels"), (int) p->nchanls);
      }
      if (p->nchanls > 1) {
        if (p->channel == ALLCHNLS)
          csound->Message(csound, Str(", reading %s channels"),
                                  (p->nchanls == 2 ? Str("both") : Str("all")));
        else
          csound->Message(csound, Str(", reading channel %d"),
                                  (int) p->channel);
      }
      csound->Message(csound, Str("\nopening %s infile %s\n"),
                              type2string(p->filetyp), sfname);
    }
    p->audrem = (int64_t) sfinfo.frames * (int64_t) sfinfo.channels;
    p->framesrem = (int64_t) sfinfo.frames;         /*   find frames rem */
    skipframes = (int) ((double) p->skiptime * (double) p->sr
                        + (p->skiptime >= FL(0.0) ? 0.5 : -0.5));
    if (skipframes < 0) {
      n = -skipframes;
      if (UNLIKELY(n > framesinbuf)) {
        csound->ErrorMsg(csound, Str("soundin: invalid skip time"));
        goto err_return;
      }
      n *= (int) sfinfo.channels;
      p->inbufp = &(p->inbuf[0]);
      p->bufend = p->inbufp;
      do {
        *(p->bufend++) = FL(0.0);
      } while (--n);
    }
    else if (skipframes < framesinbuf) {        /* if sound within 1st buf */
      n = sreadin(csound, p->sinfd, p->inbuf, p->bufsmps, p);
      p->bufend = &(p->inbuf[0]) + n;
      p->inbufp = &(p->inbuf[0]) + (skipframes * (int) sfinfo.channels);
      if (p->inbufp >= p->bufend) {
        p->inbufp = p->bufend;
        p->audrem = (int64_t) 0;
        p->endfile = 1;
      }
    }
    else if ((int64_t) skipframes >= p->framesrem) {
      n = framesinbuf * (int) sfinfo.channels;
      p->inbufp = &(p->inbuf[0]);
      p->bufend = p->inbufp;
      do {
        *(p->bufend++) = FL(0.0);
      } while (--n);
      p->audrem = (int64_t) 0;
      p->endfile = 1;
    }
    else {                                      /* for greater skiptime: */
      /* else seek to bndry */
      if (UNLIKELY(sf_seek(p->sinfd, (sf_count_t) skipframes, SEEK_SET) < 0)) {
        csound->ErrorMsg(csound, Str("soundin seek error"));
        goto err_return;
      }
      /* now rd fulbuf */
      if ((n = sreadin(csound, p->sinfd, p->inbuf, p->bufsmps, p)) == 0)
        p->endfile = 1;
      p->inbufp = p->inbuf;
      p->bufend = p->inbuf + n;
    }
    if (p->framesrem != (int64_t) -1)
      p->framesrem -= (int64_t) skipframes;     /* sampleframes to EOF   */

    return p->sinfd;                            /* return the active fd  */

 err_return:
    if (p->fd != NULL)
      csound->FileClose(csound, p->fd);
    p->sinfd = NULL;
    p->fd = NULL;
    return NULL;
}