int IOopen (char *kind, char *name, char *mode, char *fmt) { io_t *p; int type; char *path, *command; int i; int count = 0; if (strcmp (kind, "file") == 0) type = IO_FILE; else if (strcmp (kind, "pipe") == 0) type = IO_PIPE; else return -1; for (i = 0; i < ion; i++) if (!iop[i].inuse) break; if (i == ion) { iop = Marraygrow (iop, (long) (ion + IOINCR) * IOSIZE); for (i = ion + IOINCR - 1; i >= ion; i--) iop[i].inuse = FALSE; i++, ion += IOINCR; } p = &iop[i]; p->type = type; if (!(p->buf = malloc (IOBUFSIZE))) panic1 (POS, "IOopen", "malloc failed"); p->buf[0] = 0; switch (type) { case IO_FILE: if (!(p->ifp = p->ofp = fopen (name, mode))) { path = buildpath (name, FALSE); if (!path || !(p->ifp = p->ofp = fopen (path, mode))) return -1; } break; case IO_PIPE: if (!fmt) fmt = "%e"; if ( !(path = buildpath (name, TRUE)) || !(command = buildcommand (path, NULL, -1, -1, fmt)) ) return -1; pipeopen (command, &p->ifp, &p->ofp, &p->pid); if (!p->ifp || !p->ofp) return -1; break; } p->inuse = TRUE; return i; }
static void CalcReplayGain ( const char* filename, gain_info_t* G ) { FILE* fp; float buffl [NO]; float buffr [NO]; Int16_t buff [NO] [2]; size_t i; size_t len; size_t lastlen = 0; unsigned int max = 0; float level; float mult; if ((fp = pipeopen ( "mppdec --silent --scale 0.5 --gain 0 --raw - - < #", filename)) == NULL) { stderr_printf ( "Can't decode '%s'\n", filename ); exit (9); } memset ( buff, 0, sizeof(buff) ); G->Silence = 0; lastlen = len = fread (buff, 4, NO, fp); for ( i = 0; i < len; i++ ) { buffl [i] = 2. * buff [i] [0]; buffr [i] = 2. * buff [i] [1]; if ( abs(buff[i][0]) > max ) max = abs(buff[i][0]); if ( abs(buff[i][1]) > max ) max = abs(buff[i][1]); } AnalyzeSamples ( buffl, buffr, len, 2 ); level = 0.; mult = 1.; for ( i = 0; i < len; i++ ) { level += mult * (buff [i] [0] * buff [i] [0] + buff [i] [1] * buff [i] [1]); mult *= 0.95; } level = 2*sqrt(level * 0.05); if ( level > LEVEL_THR ) G->Silence |= 2; sh ( NULL, level ); while (( len = fread (buff, 4, NO, fp) ) > 0 ) { lastlen = len; for ( i = 0; i < len; i++ ) { buffl [i] = 2. * buff [i] [0]; buffr [i] = 2. * buff [i] [1]; if ( abs(buff[i][0]) > max ) max = abs(buff[i][0]); if ( abs(buff[i][1]) > max ) max = abs(buff[i][1]); } AnalyzeSamples ( buffl, buffr, len, 2 ); } level = 0.; mult = 1.; for ( i = 1; i <= NO; i++ ) { int idx = (lastlen + NO - i) % NO; level += mult * (buff [idx] [0] * buff [idx] [0] + buff [idx] [1] * buff [idx] [1]); mult *= 0.95; } level = 2*sqrt(level * 0.05); if ( level > LEVEL_THR ) G->Silence |= 1; sh(filename,level); PCLOSE (fp); #if 0 GetTitleDynamics (); #endif G -> FileName = filename; G -> TitleGain = GetTitleGain (); G -> TitlePeak = 2 * max + 1; G -> AlbumGain = GetAlbumGain (); G -> AlbumPeak = G->AlbumPeak < G->TitlePeak ? G->TitlePeak : G->AlbumPeak; return; }