<commit_before>/*
    musmon.c:

    Copyright (C) 1991,2002 <NAME>, <NAME>,
                            <NAME>, <NAME>

    This file is part of Csound.

    The Csound Library is free software; you can redistribute it
    and/or modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    Csound is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Csound; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA
*/
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif

#include "cs.h"                 /*                         MUSMON.C     */
#include "cscore.h"
#include "midiops.h"
#include "soundio.h"
#include "namedins.h"
#include "oload.h"
#include <math.h>

#define SEGAMPS 01
#define SORMSG  02

extern  int     MIDIinsert(ENVIRON *, int, MCHNBLK*, MEVENT*);
extern  int     insert(ENVIRON *, int, EVTBLK*);
extern  void    print_benchmark_info(void*, const char*);     /* main.c */
extern  void    MidiOpen(void *);
extern  void    m_chn_init_all(ENVIRON *);
extern  void    scsort(ENVIRON *, FILE *, FILE *);
extern  void    infoff(ENVIRON*, MYFLT), orcompact(ENVIRON*);
extern  void    beatexpire(ENVIRON *, double), timexpire(ENVIRON *, double);
extern  void    sfopenin(void*), sfopenout(void*), sfnopenout(ENVIRON *);
extern  void    iotranset(ENVIRON*), sfclosein(void*), sfcloseout(void*);
extern  void    MidiClose(ENVIRON*);
extern  void    RTclose(void*);
extern  char    **csoundGetSearchPathFromEnv(ENVIRON *, const char *);

static  int     playevents(ENVIRON *);

typedef struct evt_cb_func {
    void    (*func)(void *, void *);
    void    *userData;
    struct evt_cb_func  *nxt;
} EVT_CB_FUNC;

typedef struct {
    long    srngcnt[MAXCHNLS], orngcnt[MAXCHNLS];
    short   srngflg;
    short   sectno;
    int     lplayed;
    int     segamps, sormsg;
    EVENT   **ep, **epend;      /* pointers for stepping through lplay list */
    EVENT   *lsect;
} MUSMON_GLOBALS;

#define ST(x)   (((MUSMON_GLOBALS*) ((ENVIRON*) csound)->musmonGlobals)->x)

static void settempo(ENVIRON *csound, MYFLT tempo)
{
    if (tempo > FL(0.0)) {
      csound->sensEvents_state.beatTime = 60.0 / (double) tempo;
      csound->sensEvents_state.curBeat_inc =
                        (double) tempo / (60.0 * (double) csound->global_ekr);
    }
}

int gettempo(ENVIRON *csound, GTEMPO *p)
{
    if (csound->oparms->Beatmode)
      *p->ans = (MYFLT) (60.0 / csound->sensEvents_state.beatTime);
    else
      *p->ans = FL(60.0);
    return OK;
}

int tempset(ENVIRON *csound, TEMPO *p)
{
    MYFLT tempo;

    if ((tempo = *p->istartempo) <= FL(0.0)) {
      return csound->InitError(csound, Str("illegal istartempo value"));
    }
    settempo(csound, tempo);
    p->prvtempo = tempo;
    return OK;
}

int tempo(ENVIRON *csound, TEMPO *p)
{
    if (*p->ktempo != p->prvtempo) {
      settempo(csound, *p->ktempo);
      p->prvtempo = *p->ktempo;
    }
    return OK;
}

void musRESET(ENVIRON *csound)
{
    /* belt, braces, and parachute */
    int i;

    if (csound->musmonGlobals != NULL) {
      csound->Free(csound, csound->musmonGlobals);
      csound->musmonGlobals = NULL;
    }
    for (i = 0; i < MAXCHNLS; i++) {
      csound->maxamp[i]   = FL(0.0);
      csound->smaxamp[i]  = FL(0.0);
      csound->omaxamp[i]  = FL(0.0);
      csound->rngcnt[i]   = 0;
      csound->omaxpos[i]  = csound->smaxpos[i] = csound->maxpos[i] = 1;
    }
    csound->rngflg      = 0;
    csound->multichan   = 0;
}

static void print_maxamp(ENVIRON *csound, MYFLT x)
{
    if (!(csound->oparms->msglevel & 0x60)) {   /* 0x00: raw amplitudes */
      if (csound->e0dbfs > FL(3000.0))
        csound->Message(csound, "%9.1f", x);
      else if (csound->e0dbfs < FL(3.0))
        csound->Message(csound, "%9.5f", x);
      else if (csound->e0dbfs > FL(300.0))
        csound->Message(csound, "%9.2f", x);
      else if (csound->e0dbfs > FL(30.0))
        csound->Message(csound, "%9.3f", x);
      else
        csound->Message(csound, "%9.4f", x);
    }
    else {                              /* dB values */
      int   attr = 0;
      MYFLT y = x / csound->e0dbfs;     /* relative level */
      if (y < FL(1.0e-10)) {
        /* less than -200 dB: print zero */
        csound->Message(csound, "      0  ");
        return;
      }
      y = FL(20.0) * (MYFLT) log10((double) y);
      if (csound->oparms->msglevel & 0x40) {
        if (y >= FL(0.0))                               /* >= 0 dB: red */
          attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_RED;
        else if (csound->oparms->msglevel & 0x20) {
          if (y >= FL(-6.0))                            /* -6..0 dB: yellow */
            attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_YELLOW;
          else if (y >= FL(-24.0))                      /* -24..-6 dB: green */
            attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_GREEN;
          else                                          /* -200..-24 dB: blue */
            attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_BLUE;
        }
      }
      csound->MessageS(csound, attr, "%+9.2f", y);
    }
}

int musmon2(ENVIRON *csound);

int musmon(ENVIRON *csound)
{
    OPARMS  *O = csound->oparms;

#ifdef USE_DOUBLE
#ifdef BETA
    csound->Message(csound, Str("Csound version %s beta (double samples) %s\n"),
                            PACKAGE_VERSION, __DATE__);
#else
    csound->Message(csound, Str("Csound version %s (double samples) %s\n"),
                            PACKAGE_VERSION, __DATE__);
#endif
#else
#ifdef BETA
    csound->Message(csound, Str("Csound version %s beta (float samples) %s\n"),
                            PACKAGE_VERSION, __DATE__);
#else
    csound->Message(csound, Str("Csound version %s (float samples) %s\n"),
                            PACKAGE_VERSION, __DATE__);
#endif
#endif

    if (csound->musmonGlobals == NULL)
      csound->musmonGlobals = csound->Calloc(csound, sizeof(MUSMON_GLOBALS));
    /* initialise search path cache */
    csoundGetSearchPathFromEnv(csound, "SNAPDIR");
    csoundGetSearchPathFromEnv(csound, "SFDIR;SSDIR;INCDIR");
    csoundGetSearchPathFromEnv(csound, "SFDIR");
    csoundGetSearchPathFromEnv(csound, "SADIR");
    csoundGetSearchPathFromEnv(csound, "SFDIR;SSDIR");
    m_chn_init_all(csound);     /* allocate MIDI channels */
    dispinit(csound);           /* initialise graphics or character display */
    oload(csound);              /* set globals and run inits */

    /* kperf() will not call csoundYield() more than 500 times per second */
    csound->evt_poll_cnt = 0;
    csound->evt_poll_maxcnt = (int) ((double) csound->ekr / 500.0);
    /* initialise sensevents state */
    {
      sensEvents_t  *p;
      p = &(csound->sensEvents_state);
      memset(p, 0, sizeof(sensEvents_t));
      p->prvbt = p->curbt = p->nxtbt = 0.0;
      p->curp2 = p->nxtim = p->timeOffs = p->beatOffs = 0.0;
      p->curTime = p->curBeat = 0.0;
      p->curTime_inc = p->curBeat_inc = 1.0 / (double) csound->ekr;
    }
    /* if performing from beats, set the initial tempo */
    if (O->Beatmode)
      settempo(csound, (MYFLT) O->cmdTempo);
    else
      settempo(csound, FL(60.0));
    /* Enable musmon to handle external MIDI input, if it has been enabled. */
    if (O->Midiin || O->FMidiin) {
      O->RTevents = 1;
      MidiOpen(csound);         /*   alloc bufs & open files    */
    }
    csound->Message(csound, Str("orch now loaded\n"));

    csound->multichan = (csound->nchnls > 1) ? 1:0;
    ST(segamps) = O->msglevel & SEGAMPS;
    ST(sormsg) = O->msglevel & SORMSG;

    if (O->Linein) RTLineset(csound);   /* if realtime input expected     */
    if (O->outbufsamps < 0) {           /* if k-aligned iobufs requested  */
      /* set from absolute value */
      O->outbufsamps *= -(csound->ksmps);
      O->inbufsamps = O->outbufsamps;
      csound->Message(csound, Str("k-period aligned audio buffering\n"));
    }
    /* else keep the user values */
    if (!O->oMaxLag)
      O->oMaxLag = IODACSAMPS;
    if (!O->inbufsamps)
      O->inbufsamps = IOBUFSAMPS;
    if (!O->outbufsamps)
      O->outbufsamps = IOBUFSAMPS;
    /* IV - Feb 04 2005: make sure that buffer sizes for real time audio */
    /* are usable */
    if (O->infilename != NULL &&
        (strncmp(O->infilename, "adc", 3) == 0 ||
         strncmp(O->infilename, "devaudio", 8) == 0)) {
      O->oMaxLag = ((O->oMaxLag + O->inbufsamps - 1) / O->inbufsamps)
                   * O->inbufsamps;
      if (O->oMaxLag <= O->inbufsamps)
        O->inbufsamps >>= 1;
      O->outbufsamps = O->inbufsamps;
    }
    if (O->outfilename != NULL &&
        (strncmp(O->outfilename, "dac", 3) == 0 ||
         strncmp(O->outfilename, "devaudio", 8) == 0)) {
      O->oMaxLag = ((O->oMaxLag + O->outbufsamps - 1) / O->outbufsamps)
                   * O->outbufsamps;
      if (O->oMaxLag <= O->outbufsamps)
        O->outbufsamps >>= 1;
      O->inbufsamps = O->outbufsamps;
    }
    csound->Message(csound, Str("audio buffered in %d sample-frame blocks\n"),
                            (int) O->outbufsamps);
    O->inbufsamps *= csound->nchnls;    /* now adjusted for n channels  */
    O->outbufsamps *= csound->nchnls;
    if (O->sfread)                      /* if audio-in requested,       */
      sfopenin(csound);                 /*   open the infile or device  */
    if (O->sfwrite)                     /* if audio-out requested,      */
      sfopenout(csound);                /*   open the outfile or device */
    else
      sfnopenout(csound);
    iotranset(csound);          /* point recv & tran to audio formatter */

    /*        if (!O->Linein) { */  /*  *************** */
    if (!(csound->scfp = fopen(O->playscore, "r"))) {
      if (!O->Linein) {
        csoundDie(csound, Str("cannot reopen %s"), O->playscore);
      }
    }
    if (O->usingcscore) {
      if (ST(lsect) == NULL) {
        ST(lsect) = (EVENT *) mmalloc(csound, (long)sizeof(EVENT));
        ST(lsect)->op = 'l';
      }
      csound->Message(csound, Str("using Cscore processing\n"));
      /* override stdout in */
      if (!(csound->oscfp = fopen("cscore.out", "w")))
        csoundDie(csound, Str("cannot create cscore.out"));
      /* rdscor for cscorefns */
      cscorinit(csound);
      cscore(csound);      /* call cscore, optionally re-enter via lplay() */
      fclose(csound->oscfp); csound->oscfp = NULL;
      fclose(csound->scfp); csound->scfp = NULL;
      if (ST(lplayed)) return 0;

      if (!(csound->scfp = fopen("cscore.out", "r"))) /*  rd from cscore.out */
        csoundDie(csound, Str("cannot reopen cscore.out"));
      if (!(csound->oscfp = fopen("cscore.srt", "w"))) /* writ to cscore.srt */
        csoundDie(csound, Str("cannot reopen cscore.srt"));
      csound->Message(csound, Str("sorting cscore.out ..\n"));
      scsort(csound, csound->scfp, csound->oscfp);  /* call the sorter again */<commit_msg>Call iotranset() before opening sound I/O, and not after<commit_after>/*
    musmon.c:

    Copyright (C) 1991,2002 <NAME>, <NAME>,
                            <NAME>, <NAME>

    This file is part of Csound.

    The Csound Library is free software; you can redistribute it
    and/or modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    Csound is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Csound; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA
*/
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif

#include "cs.h"                 /*                         MUSMON.C     */
#include "cscore.h"
#include "midiops.h"
#include "soundio.h"
#include "namedins.h"
#include "oload.h"
#include <math.h>

#define SEGAMPS 01
#define SORMSG  02

extern  int     MIDIinsert(ENVIRON *, int, MCHNBLK*, MEVENT*);
extern  int     insert(ENVIRON *, int, EVTBLK*);
extern  void    print_benchmark_info(void*, const char*);     /* main.c */
extern  void    MidiOpen(void *);
extern  void    m_chn_init_all(ENVIRON *);
extern  void    scsort(ENVIRON *, FILE *, FILE *);
extern  void    infoff(ENVIRON*, MYFLT), orcompact(ENVIRON*);
extern  void    beatexpire(ENVIRON *, double), timexpire(ENVIRON *, double);
extern  void    sfopenin(void*), sfopenout(void*), sfnopenout(ENVIRON *);
extern  void    iotranset(ENVIRON*), sfclosein(void*), sfcloseout(void*);
extern  void    MidiClose(ENVIRON*);
extern  void    RTclose(void*);
extern  char    **csoundGetSearchPathFromEnv(ENVIRON *, const char *);

static  int     playevents(ENVIRON *);

typedef struct evt_cb_func {
    void    (*func)(void *, void *);
    void    *userData;
    struct evt_cb_func  *nxt;
} EVT_CB_FUNC;

typedef struct {
    long    srngcnt[MAXCHNLS], orngcnt[MAXCHNLS];
    short   srngflg;
    short   sectno;
    int     lplayed;
    int     segamps, sormsg;
    EVENT   **ep, **epend;      /* pointers for stepping through lplay list */
    EVENT   *lsect;
} MUSMON_GLOBALS;

#define ST(x)   (((MUSMON_GLOBALS*) ((ENVIRON*) csound)->musmonGlobals)->x)

static void settempo(ENVIRON *csound, MYFLT tempo)
{
    if (tempo > FL(0.0)) {
      csound->sensEvents_state.beatTime = 60.0 / (double) tempo;
      csound->sensEvents_state.curBeat_inc =
                        (double) tempo / (60.0 * (double) csound->global_ekr);
    }
}

int gettempo(ENVIRON *csound, GTEMPO *p)
{
    if (csound->oparms->Beatmode)
      *p->ans = (MYFLT) (60.0 / csound->sensEvents_state.beatTime);
    else
      *p->ans = FL(60.0);
    return OK;
}

int tempset(ENVIRON *csound, TEMPO *p)
{
    MYFLT tempo;

    if ((tempo = *p->istartempo) <= FL(0.0)) {
      return csound->InitError(csound, Str("illegal istartempo value"));
    }
    settempo(csound, tempo);
    p->prvtempo = tempo;
    return OK;
}

int tempo(ENVIRON *csound, TEMPO *p)
{
    if (*p->ktempo != p->prvtempo) {
      settempo(csound, *p->ktempo);
      p->prvtempo = *p->ktempo;
    }
    return OK;
}

void musRESET(ENVIRON *csound)
{
    /* belt, braces, and parachute */
    int i;

    if (csound->musmonGlobals != NULL) {
      csound->Free(csound, csound->musmonGlobals);
      csound->musmonGlobals = NULL;
    }
    for (i = 0; i < MAXCHNLS; i++) {
      csound->maxamp[i]   = FL(0.0);
      csound->smaxamp[i]  = FL(0.0);
      csound->omaxamp[i]  = FL(0.0);
      csound->rngcnt[i]   = 0;
      csound->omaxpos[i]  = csound->smaxpos[i] = csound->maxpos[i] = 1;
    }
    csound->rngflg      = 0;
    csound->multichan   = 0;
}

static void print_maxamp(ENVIRON *csound, MYFLT x)
{
    if (!(csound->oparms->msglevel & 0x60)) {   /* 0x00: raw amplitudes */
      if (csound->e0dbfs > FL(3000.0))
        csound->Message(csound, "%9.1f", x);
      else if (csound->e0dbfs < FL(3.0))
        csound->Message(csound, "%9.5f", x);
      else if (csound->e0dbfs > FL(300.0))
        csound->Message(csound, "%9.2f", x);
      else if (csound->e0dbfs > FL(30.0))
        csound->Message(csound, "%9.3f", x);
      else
        csound->Message(csound, "%9.4f", x);
    }
    else {                              /* dB values */
      int   attr = 0;
      MYFLT y = x / csound->e0dbfs;     /* relative level */
      if (y < FL(1.0e-10)) {
        /* less than -200 dB: print zero */
        csound->Message(csound, "      0  ");
        return;
      }
      y = FL(20.0) * (MYFLT) log10((double) y);
      if (csound->oparms->msglevel & 0x40) {
        if (y >= FL(0.0))                               /* >= 0 dB: red */
          attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_RED;
        else if (csound->oparms->msglevel & 0x20) {
          if (y >= FL(-6.0))                            /* -6..0 dB: yellow */
            attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_YELLOW;
          else if (y >= FL(-24.0))                      /* -24..-6 dB: green */
            attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_GREEN;
          else                                          /* -200..-24 dB: blue */
            attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_BLUE;
        }
      }
      csound->MessageS(csound, attr, "%+9.2f", y);
    }
}

int musmon2(ENVIRON *csound);

int musmon(ENVIRON *csound)
{
    OPARMS  *O = csound->oparms;

#ifdef USE_DOUBLE
#ifdef BETA
    csound->Message(csound, Str("Csound version %s beta (double samples) %s\n"),
                            PACKAGE_VERSION, __DATE__);
#else
    csound->Message(csound, Str("Csound version %s (double samples) %s\n"),
                            PACKAGE_VERSION, __DATE__);
#endif
#else
#ifdef BETA
    csound->Message(csound, Str("Csound version %s beta (float samples) %s\n"),
                            PACKAGE_VERSION, __DATE__);
#else
    csound->Message(csound, Str("Csound version %s (float samples) %s\n"),
                            PACKAGE_VERSION, __DATE__);
#endif
#endif

    if (csound->musmonGlobals == NULL)
      csound->musmonGlobals = csound->Calloc(csound, sizeof(MUSMON_GLOBALS));
    /* initialise search path cache */
    csoundGetSearchPathFromEnv(csound, "SNAPDIR");
    csoundGetSearchPathFromEnv(csound, "SFDIR;SSDIR;INCDIR");
    csoundGetSearchPathFromEnv(csound, "SFDIR");
    csoundGetSearchPathFromEnv(csound, "SADIR");
    csoundGetSearchPathFromEnv(csound, "SFDIR;SSDIR");
    m_chn_init_all(csound);     /* allocate MIDI channels */
    dispinit(csound);           /* initialise graphics or character display */
    oload(csound);              /* set globals and run inits */

    /* kperf() will not call csoundYield() more than 500 times per second */
    csound->evt_poll_cnt = 0;
    csound->evt_poll_maxcnt = (int) ((double) csound->ekr / 500.0);
    /* initialise sensevents state */
    {
      sensEvents_t  *p;
      p = &(csound->sensEvents_state);
      memset(p, 0, sizeof(sensEvents_t));
      p->prvbt = p->curbt = p->nxtbt = 0.0;
      p->curp2 = p->nxtim = p->timeOffs = p->beatOffs = 0.0;
      p->curTime = p->curBeat = 0.0;
      p->curTime_inc = p->curBeat_inc = 1.0 / (double) csound->ekr;
    }
    /* if performing from beats, set the initial tempo */
    if (O->Beatmode)
      settempo(csound, (MYFLT) O->cmdTempo);
    else
      settempo(csound, FL(60.0));
    /* Enable musmon to handle external MIDI input, if it has been enabled. */
    if (O->Midiin || O->FMidiin) {
      O->RTevents = 1;
      MidiOpen(csound);         /*   alloc bufs & open files    */
    }
    csound->Message(csound, Str("orch now loaded\n"));

    csound->multichan = (csound->nchnls > 1) ? 1:0;
    ST(segamps) = O->msglevel & SEGAMPS;
    ST(sormsg) = O->msglevel & SORMSG;

    if (O->Linein) RTLineset(csound);   /* if realtime input expected     */
    if (O->outbufsamps < 0) {           /* if k-aligned iobufs requested  */
      /* set from absolute value */
      O->outbufsamps *= -(csound->ksmps);
      O->inbufsamps = O->outbufsamps;
      csound->Message(csound, Str("k-period aligned audio buffering\n"));
    }
    /* else keep the user values */
    if (!O->oMaxLag)
      O->oMaxLag = IODACSAMPS;
    if (!O->inbufsamps)
      O->inbufsamps = IOBUFSAMPS;
    if (!O->outbufsamps)
      O->outbufsamps = IOBUFSAMPS;
    /* IV - Feb 04 2005: make sure that buffer sizes for real time audio */
    /* are usable */
    if (O->infilename != NULL &&
        (strncmp(O->infilename, "adc", 3) == 0 ||
         strncmp(O->infilename, "devaudio", 8) == 0)) {
      O->oMaxLag = ((O->oMaxLag + O->inbufsamps - 1) / O->inbufsamps)
                   * O->inbufsamps;
      if (O->oMaxLag <= O->inbufsamps)
        O->inbufsamps >>= 1;
      O->outbufsamps = O->inbufsamps;
    }
    if (O->outfilename != NULL &&
        (strncmp(O->outfilename, "dac", 3) == 0 ||
         strncmp(O->outfilename, "devaudio", 8) == 0)) {
      O->oMaxLag = ((O->oMaxLag + O->outbufsamps - 1) / O->outbufsamps)
                   * O->outbufsamps;
      if (O->oMaxLag <= O->outbufsamps)
        O->outbufsamps >>= 1;
      O->inbufsamps = O->outbufsamps;
    }
    csound->Message(csound, Str("audio buffered in %d sample-frame blocks\n"),
                            (int) O->outbufsamps);
    O->inbufsamps *= csound->nchnls;    /* now adjusted for n channels  */
    O->outbufsamps *= csound->nchnls;
    iotranset(csound);          /* point recv & tran to audio formatter */
    if (O->sfread)                      /* if audio-in requested,       */
      sfopenin(csound);                 /*   open the infile or device  */
    if (O->sfwrite)                     /* if audio-out requested,      */
      sfopenout(csound);                /*   open the outfile or device */
    else
      sfnopenout(csound);

    /*        if (!O->Linein) { */  /*  *************** */
    if (!(csound->scfp = fopen(O->playscore, "r"))) {
      if (!O->Linein) {
        csoundDie(csound, Str("cannot reopen %s"), O->playscore);
      }
    }
    if (O->usingcscore) {
      if (ST(lsect) == NULL) {
        ST(lsect) = (EVENT *) mmalloc(csound, (long)sizeof(EVENT));
        ST(lsect)->op = 'l';
      }
      csound->Message(csound, Str("using Cscore processing\n"));
      /* override stdout in */
      if (!(csound->oscfp = fopen("cscore.out", "w")))
        csoundDie(csound, Str("cannot create cscore.out"));
      /* rdscor for cscorefns */
      cscorinit(csound);
      cscore(csound);      /* call cscore, optionally re-enter via lplay() */
      fclose(csound->oscfp); csound->oscfp = NULL;
      fclose(csound->scfp); csound->scfp = NULL;
      if (ST(lplayed)) return 0;

      if (!(csound->scfp = fopen("cscore.out", "r"))) /*  rd from cscore.out */
        csoundDie(csound, Str("cannot reopen cscore.out"));
      if (!(csound->oscfp = fopen("cscore.srt", "w"))) /* writ to cscore.srt */
        csoundDie(csound, Str("cannot reopen cscore.srt"));
      csound->Message(csound, Str("sorting cscore.out ..\n"));
      scsort(csound, csound->scfp, csound->oscfp);  /* call the sorter again */
{'fraction_non_alphanumeric': 0.15151918385451318, 'fraction_numerical': 0.01561321800842759, 'mean_word_length': 2.2904261529480445, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 335, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3254029', 'n_tokens_mistral': 8429, 'n_tokens_neox': 8016, 'n_words': 1868}