// --------------------------------------------------------------------------- // frequencyAt // --------------------------------------------------------------------------- //! Return the interpolated frequency (in Hz) of this Partial at the //! specified time. At times beyond the ends of the Partial, return //! the frequency at the nearest envelope endpoint. Throw an //! InvalidPartial exception if this Partial has no Breakpoints. // double Partial::frequencyAt( double time ) const { if ( numBreakpoints() == 0 ) { Throw( InvalidPartial, "Tried to interpolate a Partial with no Breakpoints." ); } // lower_bound returns a reference to the lowest // position that would be higher than an element // having key equal to time: Partial::const_iterator it = findAfter( time ); if ( it == begin() ) { // time is before the onset of the Partial: return it.breakpoint().frequency(); } else if ( it == end() ) { // time is past the end of the Partial: return (--it).breakpoint().frequency(); } else { // interpolate between it and its predeccessor // (we checked already that it is not begin): const Breakpoint & hi = it.breakpoint(); double hitime = it.time(); const Breakpoint & lo = (--it).breakpoint(); double lotime = it.time(); double alpha = (time - lotime) / (hitime - lotime); return (alpha * hi.frequency()) + ((1. - alpha) * lo.frequency()); } }
// --------------------------------------------------------------------------- // bandwidthAt // --------------------------------------------------------------------------- //! Return the interpolated bandwidth (noisiness) coefficient of //! this Partial at the specified time. At times beyond the ends of //! the Partial, return the bandwidth coefficient at the nearest //! envelope endpoint. Throw an InvalidPartial exception if this //! Partial has no Breakpoints. // double Partial::bandwidthAt( double time ) const { if ( numBreakpoints() == 0 ) { Throw( InvalidPartial, "Tried to interpolate a Partial with no Breakpoints." ); } // findAfter returns the position of the earliest // Breakpoint later than time, or the end // position if no such Breakpoint exists: Partial::const_iterator it = findAfter( time ); if ( it == begin() ) { // time is before the onset of the Partial: return it.breakpoint().bandwidth(); } else if (it == end() ) { // time is past the end of the Partial: return (--it).breakpoint().bandwidth(); } else { // interpolate between it and its predeccessor // (we checked already that it is not begin): const Breakpoint & hi = it.breakpoint(); double hitime = it.time(); const Breakpoint & lo = (--it).breakpoint(); double lotime = it.time(); double alpha = (time - lotime) / (hitime - lotime); return (alpha * hi.bandwidth()) + ((1. - alpha) * lo.bandwidth()); } }
// --------------------------------------------------------------------------- // findNearest (non-const version) // --------------------------------------------------------------------------- //! Return the insertion position for the Breakpoint nearest //! the specified time. Always returns a valid iterator (the //! position of the nearest-in-time Breakpoint) unless there //! are no Breakpoints. // Partial::iterator Partial::findNearest( double time ) { // if there are no Breakpoints, return end: if ( numBreakpoints() == 0 ) { return end(); } // get the position of the first Breakpoint after time: Partial::iterator pos = findAfter( time ); // if there is an earlier Breakpoint that is closer in // time, prefer that one: if ( pos != begin() ) { Partial::iterator prev = pos; --prev; if ( pos == end() || pos.time() - time > time - prev.time() ) { return prev; } } // failing all else: return pos; }
// --------------------------------------------------------------------------- // phaseAt // --------------------------------------------------------------------------- //! Return the interpolated phase (in radians) of this Partial at //! the specified time. At times beyond the ends of the Partial, //! return the extrapolated from the nearest envelope endpoint //! (assuming constant frequency, as reported by frequencyAt()). //! Throw an InvalidPartial exception if this Partial has no //! Breakpoints. // double Partial::phaseAt( double time ) const { if ( numBreakpoints() == 0 ) { Throw( InvalidPartial, "Tried to interpolate a Partial with no Breakpoints." ); } // findAfter returns the position of the earliest // Breakpoint later than time, or the end // position if no such Breakpoint exists: Partial::const_iterator it = findAfter( time ); // compute phase: if ( it == begin() ) { // time is before the onset of the Partial: double dp = 2. * Pi * (it.time() - time) * it.breakpoint().frequency(); return std::fmod( it.breakpoint().phase() - dp, 2. * Pi); } else if (it == end() ) { // time is past the end of the Partial: // ( first decrement iterator to get the tail Breakpoint) --it; double dp = 2. * Pi * (time - it.time()) * it.breakpoint().frequency(); return std::fmod( it.breakpoint().phase() + dp, 2. * Pi ); } else { // interpolate between it and its predeccessor // (we checked already that it is not begin): const Breakpoint & hi = it.breakpoint(); double hitime = it.time(); const Breakpoint & lo = (--it).breakpoint(); double lotime = it.time(); double alpha = (time - lotime) / (hitime - lotime); double finterp = ( alpha * hi.frequency() ) + ( ( 1. - alpha ) * lo.frequency() ); // need to keep fmod in here because other stuff // (Spc export and sdif export, for example) rely // on it: if ( alpha < 0.5 ) { double favg = 0.5 * ( lo.frequency() + finterp ); double dp = 2. * Pi * (time - lotime) * favg; return std::fmod( lo.phase() + dp, 2. * Pi ); } else { double favg = 0.5 * ( hi.frequency() + finterp ); double dp = 2. * Pi * (hitime - time) * favg; return std::fmod( hi.phase() - dp, 2. * Pi ); } } }
void fgrepOne(char *pattern, char *fileName, boolean ignoreCase, boolean singleFile) /* Gnarly, speed tweaked, unbuffered i/o grep. Why? Because it's * 4x faster, which matters on those huge GenBank files! */ { char buf[8*1024+1]; int bufRead; int remainder = 0; int fd; char *s; int patSize = strlen(pattern); char *(*searcher)(const char *string, const char *pat); searcher = (ignoreCase ? findInString : strstr); fd = open(fileName, _O_RDONLY|_O_BINARY); if (fd < 0) errAbort("Couldn't open %s\n", fileName); for (;;) { bufRead = read(fd, buf + remainder, sizeof(buf)-1-remainder) + remainder; if (bufRead == 0) break; buf[bufRead] = 0; s = buf; while ((s = searcher(s, pattern)) != NULL) { char *lineStart = findBefore(buf, s, '\n'); char *lineAfter = findAfter(s, buf+bufRead, '\n'); if (lineAfter[-1] == '\r') --lineAfter; if (!singleFile) printf("%s: ", fileName); mustWrite(stdout, lineStart, lineAfter-lineStart); putchar('\n'); s += patSize; } s = findBefore(buf, buf+bufRead, '\n'); if (s == buf) remainder = 0; else { remainder = buf + bufRead - s; memmove(buf, s, remainder); } if (bufRead < sizeof(buf)-1) break; } close(fd); }
// --------------------------------------------------------------------------- // amplitudeAt // --------------------------------------------------------------------------- //! Return the interpolated amplitude of this Partial at the //! specified time. Throw an InvalidPartial exception if this //! Partial has no Breakpoints. If non-zero fadeTime is specified, //! then the amplitude at the ends of the Partial is coomputed using //! a linear fade. The default fadeTime is ShortestSafeFadeTime, //! see the definition of ShortestSafeFadeTime, above. // double Partial::amplitudeAt( double time, double fadeTime ) const { if ( numBreakpoints() == 0 ) Throw( InvalidPartial, "Tried to interpolate a Partial with no Breakpoints." ); // findAfter returns the position of the earliest // Breakpoint later than time, or the end // position if no such Breakpoint exists: Partial::const_iterator it = findAfter( time ); if ( it == begin() ) { double alpha = (time < it.time()) ? 0. : 1.; if ( fadeTime > 0 ) { // fade in ampltude if time is before the onset of the Partial: alpha = std::max(0., 1. - ((it.time() - time) / fadeTime) ); } return alpha * it.breakpoint().amplitude(); } else if ( it == end() ) { // ( first decrement iterator to get the tail Breakpoint) --it; double alpha = (time > it.time()) ? 0. : 1.; if ( fadeTime > 0 ) { // fade out ampltude if time is past the end of the Partial: alpha = std::max(0., 1. - ((time - it.time()) / fadeTime) ); } return alpha * it.breakpoint().amplitude(); } else { // interpolate between it and its predeccessor // (we checked already that it is not begin): const Breakpoint & hi = it.breakpoint(); double hitime = it.time(); const Breakpoint & lo = (--it).breakpoint(); double lotime = it.time(); double alpha = (time - lotime) / (hitime - lotime); return (alpha * hi.amplitude()) + ((1. - alpha) * lo.amplitude()); } }
// --------------------------------------------------------------------------- // absorb // --------------------------------------------------------------------------- //! Absorb another Partial's energy as noise (bandwidth), //! by accumulating the other's energy as noise energy //! in the portion of this Partial's envelope that overlaps //! (in time) with the other Partial's envelope. // void Partial::absorb( const Partial & other ) { Partial::iterator it = findAfter( other.startTime() ); while ( it != end() && !(it.time() > other.endTime()) ) { // only non-null (non-zero-amplitude) Breakpoints // abosrb noise energy because null Breakpoints // are used especially to reset the Partial phase, // and are not part of the normal analyasis data: if ( it->amplitude() > 0 ) { // absorb energy from other at the time // of this Breakpoint: double a = other.amplitudeAt( it.time() ); it->addNoiseEnergy( a * a ); } ++it; } }
// --------------------------------------------------------------------------- // parametersAt // --------------------------------------------------------------------------- //! Return the interpolated parameters of this Partial at //! the specified time, same as building a Breakpoint from //! the results of frequencyAt, ampitudeAt, bandwidthAt, and //! phaseAt, but performs only one Breakpoint envelope search. //! Throw an InvalidPartial exception if this Partial has no //! Breakpoints. If non-zero fadeTime is specified, then the //! amplitude at the ends of the Partial is coomputed using a //! linear fade. The default fadeTime is ShortestSafeFadeTime. // Breakpoint Partial::parametersAt( double time, double fadeTime ) const { if ( numBreakpoints() == 0 ) { Throw( InvalidPartial, "Tried to interpolate a Partial with no Breakpoints." ); } // findAfter returns the position of the earliest // Breakpoint later than time, or the end // position if no such Breakpoint exists: Partial::const_iterator it = findAfter( time ); if ( it == begin() ) { // time is before the onset of the Partial: // frequency is starting frequency, // amplitude is 0 (or fading), bandwidth is starting // bandwidth, and phase is rolled back. double alpha = (time < it.time()) ? 0. : 1.; if ( fadeTime > 0 ) { // fade in ampltude if time is before the onset of the Partial: alpha = std::max(0., 1. - ((it.time() - time) / fadeTime) ); } double amp = alpha * it.breakpoint().amplitude(); double dp = 2. * Pi * (it.time() - time) * it.breakpoint().frequency(); double ph = std::fmod( it.breakpoint().phase() - dp, 2. * Pi); return Breakpoint( it.breakpoint().frequency(), amp, it.breakpoint().bandwidth(), ph ); } else if (it == end() ) { // time is past the end of the Partial: // frequency is ending frequency, // amplitude is 0 (or fading), bandwidth is ending // bandwidth, and phase is rolled forward. --it; double alpha = (time > it.time()) ? 0. : 1.; if ( fadeTime > 0 ) { // fade out ampltude if time is past the end of the Partial: alpha = std::max(0., 1. - ((time - it.time()) / fadeTime) ); } double amp = alpha * it.breakpoint().amplitude(); double dp = 2. * Pi * (time - it.time()) * it.breakpoint().frequency(); double ph = std::fmod( it.breakpoint().phase() + dp, 2. * Pi ); return Breakpoint( it.breakpoint().frequency(), amp, it.breakpoint().bandwidth(), ph ); } else { // interpolate between it and its predeccessor // (we checked already that it is not begin): const Breakpoint & hi = it.breakpoint(); double hitime = it.time(); const Breakpoint & lo = (--it).breakpoint(); double lotime = it.time(); double alpha = (time - lotime) / (hitime - lotime); double finterp = ( alpha * hi.frequency() ) + ( ( 1. - alpha ) * lo.frequency() ); // need to keep fmod in here because other stuff // (Spc export and sdif export, for example) rely // on it: double ph = 0; if ( alpha < 0.5 ) { double favg = 0.5 * ( lo.frequency() + finterp ); double dp = 2. * Pi * (time - lotime) * favg; ph = std::fmod( lo.phase() + dp, 2. * Pi ); } else { double favg = 0.5 * ( hi.frequency() + finterp ); double dp = 2. * Pi * (hitime - time) * favg; ph = std::fmod( hi.phase() - dp, 2. * Pi ); } return Breakpoint( (alpha * hi.frequency()) + ((1. - alpha) * lo.frequency()), (alpha * hi.amplitude()) + ((1. - alpha) * lo.amplitude()), (alpha * hi.bandwidth()) + ((1. - alpha) * lo.bandwidth()), ph ); } }