          CHANGES IN SOUNDGEN VERSION 1.6.2 [06-February-2020]
BUGS FIXED:
  * playme(): '...' removed from documentation (new CRAN requirements)

MINOR:
  * soundgen(): new argument "formantLocking" for temporarily locking a harmonic to a formant (a form of source-filter interaction)
  * soundgen(): formant drift occurs regardless of whether formants are specified as moving or static


          CHANGES IN SOUNDGEN VERSION 1.6.1 [22-January-2020]
BUGS FIXED:
  * soundgen(): stochastic formants properly added to breathing noise even without specifying VTL (bug introduced in v1.6.0)
  * soundgen(), getSpectralEnvelope(): manually specifying formant bandwidth works again (bug introduced in v1.6.0)
  * soundgen(): tempEffects(pitchDriftDep = 0) no longer crashes because removing pitch drift no longer prevents amplitude drift from working
  * transplantFormants(): step no longer conflicts with overlap
  * soundgen_app(): debugged consonant presets

MINOR:
  * soundgen(), generateNoise(): a new argument "rolloffNoiseExp" to control rolloff of the unvoiced component
  * soundgen(): if "noise" argument is numeric rather than a list, noise component is time-locked to voiced component to ensure precisely the same timing
  * soundgen(): invalidArgAction="ignore" consistently removes all limits (noise-related pars were reset to defaults in earlier versions)
  * soundgen(): change in defaults related to nonlinear phenomena: nonlinBalance defaults to 100%, with no jitter, shimmer, or subharmonics
  * soundgen(): higher default pitchSamplingRate, automatically reset to 10 * max pitch for more reliable control of syllable duration
  * soundgen(), soundgen_app(): nonlinDep is deprecated
  * soundgen(): the "interpol" parameter is applied to (almost all) types of smoothing more consistently
  * getSmoothContour(): a new argument "loessSpan" passed on to loess() for controlling the amount of smoothing of pitch contours, etc


          CHANGES IN SOUNDGEN VERSION 1.6.0 [09-December-2019]
BUGS FIXED:
  * analyze(): proper plotting of oscillogram for audio files

NEW FUNCTIONS:
  * filterSoundByMS(): manipulates the modulation spectrum of a sound (for ex., removing amplitude and/or frequency modulation above a certain threshold)
  * filterMS(): filters a modulation spectrum by removing a certain range of amplitude modulation (AM) and frequency modulation (FM) frequencies (called by filterSoundByMS)
  * invertSpectrogram(): reconstructs audio from a spectrogram by trying to guess the phase
  * specToMS(), msToSpec(): transform a spectrogram to a modulation spectrum and back again with proper AM/FM or time/frequency labels
  * transplantEnv(): transplants the amplitude envelope from one sound to another

MINOR:
  * soundgen(): vectorized vocal tract length ("vocalTract" argument) - note that this is similar to the "mouth" argument, but with bandwidths adjusted appropriately and with no limitation on the magnitude of formant frequency shifts
  * soundgen(): a new argument, "formantCeiling", adjusts the frequency to which formant are calculated - increase for extra precision, particularly for longer-than-human vocal tracts
  * playme(), soundgen(): the default player on Mac is "afplay"
  * pitch_app(): choose summary function, reset to defaults, etc.
  * analyze() and analyzeFolder() accept manually checked pitch contours as produced by pitch_app ("pitchManual" argument)
  * segment(), segmentFolder(): added oscillogram, improved accuracy of timing
  * transplantFormants() accepts spectral filter produced by getSpectralEnvelope() as an alternative to donor sound


          CHANGES IN SOUNDGEN VERSION 1.5.1 [12-October-2019]
BUGS FIXED:
  * pitch_app() runs locally, new layout, multiple new features, integrated with analyze()
  * analyze() and pitch_app(): improved accuracy of autocorrelation-based pitch tracking at high frequencies

NEW FUNCTIONS:
  * pitchSmoothPraat(): smoothes pitch contours with the same algorithm and "bandwidth" parameter as in Praat for improved compatibility
  * getPrior(): extract and/or plot the prior used for adjusting the certainty in pitch estimates in analyze()

MINOR:
  * soundgen_app(): improved tips
  * spectrogram(): option to plot frequencies on a logarithmic scale (yScale = 'log') and specify units (ms/s and Hz/kHz)
  * spectrogram(): by default pads sounds with silence so as to analyze the edges (padWithSilence = TRUE)
  * ssm(), spectrogram(), modulationSpectrum(), analyze(): standardized specification of "colorTheme"
  * analyze(): more flexible "cutFreq" defaults
  * analyze(): priorPlot and plotSpec deprecated
  * analyze(): support for plotting both spetrogram & oscillogram (finally!)


          CHANGES IN SOUNDGEN VERSION 1.5.0 [11-September-2019]
NEW FUNCTIONS:
  * pitch_app(): an interactive Shiny app for manually editing intonation (pitch) contours in a web browser

Affect back-compatibility:
  * analyze(): priorMean is now in Hz instead of semitones (but priorSD is still in semitones), priorPlot looks nicer
  * analyze(): interpolWin and cepSmooth are now in Hz instead of bins
  * analyze(): snakeStep, interpolWin, and smooth are set to 0 instead of NULL to turn off these types of pitch postprocessing

MINOR:
  * analyze(): set nFormants = 0 to skip formant analysis, SPL_measured = NULL to skip loudness analysis
  * analyze(): minor changes / debugging in pathfinding algorithms
  * playme(): supports playing a selected time region (from/to) and mp3 format
  * spectrogram(): accepts additional base graphical parameters, such as "yaxp" to control the number of tick marks; a new argument "grid" can be added to add grid lines


          CHANGES IN SOUNDGEN VERSION 1.4.1 [05-July-2019]
NEW FUNCTIONS:
  * flatSpectrum(): flattens the spectrum of a sound by smoothing in the frequency domain
  * transplantFormants(): takes the general spectral envelope (formants) of one sound and "transplants" it onto another sound

MINOR:
  * soundgen(), playme(), generateNoise(), fart(), beat(): the previously boolean argument "play" can now also be a string to specify the audio player, eg play = 'aplay' or play = 'vlc'
  * estimateVTL() offers three methods of estimating vocal tract length from formant frequencies
  * analyze() and analyzeFolder() can summarize the output with arbitrary functions like "function(x) ..."
  * analyze(), analyzeFolder(): argument "summaryStats" renamed to "summaryFun" to keep the terminology consistent with getLoudnessFolder() and getRMSFolder()
  * analyze() and analyzeFolder() also return duration without counting silent frames at the beginning/end of the sound
  * getSpectralEnvelope(): the output matrix contains frequency and time stamps as row/column names
  * spectrogram(): new output option ("complex") returns a spectrogram with imaginary parts (phase)
  * getLoudness() and getLoudnessFolder() support mp3

BUG FIXES:
  * analyze() no longer crashes with pitchMethods = NULL
  * getLoudness() and analyze() no longer crash with sampling rates above 44100 (NB: frequencies above 27 barks are automatically discarded when calculating subjective loudness)
  * morph(): proper handling of attackLen and other small debugging
  * soundgen(): tempEffects(amplDriftDep) is no longer tied to pitchDriftDep, has a more reasonable default, and doesn't affect audio normalization


          CHANGES IN SOUNDGEN VERSION 1.4.0 [13-March-2019]
MAJOR (affect back-compatibility):
  * soundgen(), fart(), beat(), generateNoise(): removed all deprecated parameters, notably "pitchAnchors", "noiseAnchors", etc. (now simply "pitch", "noise", etc.)
  * soundgen(): a new argument ("noiseAmpRef") controls how the relative amplitudes of voiced and unvoiced components are specified by the "noise" setting, with 3 options: "f0" (noise amplitude relative to first partial) produces the same results as in earlier versions of soundgen; both "source" (relative to ulfiltered voiced component) and "filtered" (relative to filtered voiced component - the new default) make noise amplitude less dependent on rolloff. The new default is thus to specify the (peak) amplitude of noise directly in relation to the (peak) amplitude of the voiced component, which is different from older versions - check your code! See vignette on sound synthesis, section 2.12.2, "Noise amplitude".

NEW FUNCTIONS:
  * modulationSpectrum(), modulationSpectrumFolder(): calculates and plots a modulation spectrum showing combined spectro-temporal modulation in one sound or all mp3/wav files in a folder, respectively
  * getRMS(), getRMSFolder(): calculates root mean square amplitude per frame in one sound or all mp3/wav files in a folder, respectively
  * normalizeFolder(): normalizes the amplitude of all wav/mp3 files in a folder based on their peak or RMS amplitude or subjective loudness
  * getLoudnessFolder(): a wrapper around getLoudness() for estimating the loudness of all audio files in a folder
  * gaussianSmooth2D(): performs Gaussian blur of spectrograms, modulation spectra, or any other numeric matrices.
  * reportTime(): provides a nicely formatted "estimated time left" in loops plus a summary upon completion

MINOR:
  * spectrogram(), getLoudness(): better temporal alignment of the waveform, spectrogram, and loudness contour
  * analyze(), analyzeFolder(): more precise time stampts for STFT frames
  * getLoudness(), analyze(): both functions produce mutually consistent estimates; option to specify the "scale" (maximum possible amplitude) of input waveforms (for audio files, the scale is determined automatically), making loudness estimates dependent on the actual vs. theoretically possible amplitude; all sounds were effectively normalized to max amplitude in earlier versions
  * soundgen_app(): more intelligent behavior of pitch range
  * Updated vignettes and demos


          CHANGES IN SOUNDGEN VERSION 1.3.2 [10-January-2019]
MINOR:
  * soundgen(): new argument "rolloffExact" for controlling the strength of each individual harmonic in source spectrum
  * soundgen(): changed behavior of the "glottis" parameter (but still experimental) for glottal pulses with a closed phase
  * soundgen(): interpolation of vectorized amDep, amShape, and amFreq changed from 'spline' to 'approx'
  * analyze(), analyzeFolder(), segment(), segmentFolder(), spectrogram(), spectrogramFolder(): support for mp3 files in addition to wav
  * analyze(): pitch candidates based on lowest dominant frequency band ("dom") respect pitchCeiling
  * Updated demos, vignettes, presets, and documentation of exported functions

BUG FIXES:
  * soundgen(), getRolloff(): rolloffOct argument now really controls the change of rolloff per octave above the fundamental frequency, as intended; note that this affects many presets, which have been updated accordingly
  * soundgen(): proper control of pitch drift with pitchDriftDep
  * soundgen(), soundgen_app(): pitchFloor and pitchCeiling fully control pitch range, without needing to override permittedValues with "invalidArgAction = 'ignore'"
  * analyze(): plotting symbols for pitch candidates in plot legend


          CHANGES IN SOUNDGEN VERSION 1.3.1 [04-October-2018]

NEW FUNCTIONS:
  * getLoudness(): estimates subjective loudness per frame, in sone

MINOR:
  * analyze(), analyzeFolder(): also return loudness per frame, in sone (new arguments: SPL_measured and Pref)
  * analyze(), analyzeFolder(): new argument "summaryStats" for specifying how to summarize the output (mean, sd, etc.)
  * analyze(): a legend can be added to plot (thanks to Jerome Sueur for the idea)
  * analyze(), analyzeFolder(), segment(), segmentFolder(), spectrogram(): plots are saved as .png instead of .jpg
  * ssm(): new arguments: "padWith" for dealing with edges and "heights" for controlling relative plot sizes
  * addFormants(): support for user-specified "spectralEnvelope" (a new argument)
  * soundgen(): adjusted bandwidth calculation for very low formant frequencies (under 250 Hz)
  * Updated vignettes and documentation of all exported functions

BUG FIXES:
  * analyzeFolder(): the result is returned with correct class (numeric instead of factor)
  * flatEnv(): fixed a bug that prevented correct removal of DC offset ("killDC")
  * generateNoise(): proper interpolation of user-specified "spectralEnvelope" (renamed from "filterNoise")
  * soundgen_app(): fixed a bug introduced in 1.3.0 that caused the app to crash when switching to a new preset
  * soundgen_app(): proper plotting of amplGlobal and spectrogram view of formantsNoise


          CHANGES IN SOUNDGEN VERSION 1.3.0 [31-August-2018]

Back-compatible with soundgen 1.2.X. The main change is abolishing the distinction between anchors (previously pitchAnchors, ampAnchors, etc.) and other vectorized arguments to soundgen (jitterDep, rolloff, etc.) Most vectorized arguments can now be either numeric vectors or dataframes.

NEW FUNCTIONS:
  * osc_dB(): draws an oscillogram (waveform) on a log-tranformed, dB scale. Analogous to the "Waveform (dB)" view in Audacity

MAJOR:
  * soundgen(), generateNoise(), beat(), fart(): the word "Anchor" is dropped from arguments (pitchAnchors, pitchAnchorsGlobal, glottisAnchors, amplAnchors, amplAnchorsGlobal, mouthAnchors, noiseAnchors). Write simply "pitch = ..., ampl = ..." instead of "pitchAnchors = ..., amplAnchors = ..."
  * soundgen(), generateNoise(), getRolloff(): vectorized arguments can be specified on a natural time scale, in the same format as all former anchors. Ex.: "jitterDep = data.frame(time = c(0, 150, 700), value = c(.2, 2, 0))". Affected arguments: vibratoFreq, vibratoDep, subFreq, subDep, jitterLen, jitterDep, shimmerLen, shimmerDep, rolloff, rolloffOct, rolloffKHz, rolloffParab, rolloffParabHarm, amDep, amFreq, amShape

MINOR:
  * soundgen() and related functions: "throwaway" is deprecated and replaced with "dynamicRange"
  * spectrogram(), soundgen_app(): added dynamic range, support for plotting the oscillogram on a dB scale, and adjustable size of spectrogram/oscillogram panels
  * soundgen_app(): fixed a bug introduced in 1.2.1 that crashed the app when changing sylLen. Thanks to Andrew Chang for pointing this out
  * Updated vignettes on sound synthesis and analysis, a new vignette on reproducing an existing sound with soundgen (webpage only, not published with the package because of large audio files)


          CHANGES IN SOUNDGEN VERSION 1.2.1 [04-August-2018]

NEW FUNCTIONS:
  * generateNoise(): a simplified version of soundgen() for producing purely voiceless vocalizations such as hissing. Unlike soundgen(), it also accepts a manually specified spectral filter of an arbitrary shape instead of formants for flexible generation of non-biological sounds

MINOR:
  * analyze(): spectral median (medianFreq) and spectral centroid (specCentroid) added as separate outputs; type ?analyze() for details
  * soundgen(): a new argument shimmerLen for controlling the period of shimmer (cf. jitterLen)
  * soundgen(): a new argument noiseFlatSpec for more advanced control of the spectrum of the unvoiced component
  * soundgen(): more intelligent automatic adjustment of pitch ceiling, floor, pitch sampling rate, and sampling rate for extreme pitch values
  * crossFade(): accepts different shapes of fade-in/out
  * flatEnv(): minor debugging, default method is now "hil" (see ?seewave::env)
  * schwa() returns relative formant frequencies in both percentages and semitones
  * Updated url's in documentation
  * Updated vignettes on sound synthesis and particularly on sound analysis, including a new section on DIY extraction of custom spectral descriptors


          CHANGES IN SOUNDGEN VERSION 1.2.0 [04-March-2018]

Back-compatibible with soundgen 1.1.x. Old code will mostly produce the same results, except for moving noise formants and amplitude envelopes in polysyllabic sounds.

MAJOR:
  * soundgen(): the argument "formantsNoise" (formants in the unvoiced component) now affects polysyllabic bouts in the same way as "formants" (formants in the voiced component), i.e. moving formants in "noiseFormants" span multiple syllables (see vignette 2.12)
  * soundgen(): vectorized parameters sylLen, pauseLen, vibratoFreq, vibratoDep, jitterDep, jitterLen, and shimmerDep. For ex., "nSyl = 15, sylLen = 300:150" produces 15 progressively shorter syllables from 300 ms to 150 ms in length (see vignette 2.5)
  * soundgen(): a new argument, "nonlinRandomWalk", for specifying the exact timing of each vocal regime (0 = none, 1 = subharmonics, 2 = subharmonics + jitter + shimmer). This is intended for making reproducible examples of sounds with nonlinear effects (see vignette 2.11.5)
  * soundgen(): "amplAnchorsGlobal" adjusts the amplitude from syllable to syllable in discrete steps, instead of applying a smooth amplitude envelope to the entire bout, and it also applies to the unvoiced component (turbulent noise)
  * depends on seewave >=2.1.0 because of changes in the seewave package

NEW FUNCTIONS:
  * spectrogramFolder(): extracts and saves spectrograms of all .wav files in a folder, creates an html file with a table of click-to-play spectrograms
  * getRandomWalk(), getIntegerRandomWalk(): functions for customizing the random walks that divide the sound into segments with different nonlinear regimes; see "nonlinRandomWalk" argument to soundgen()

MINOR:
  * soundgen(): an option to add extra stochastic formants to the unvoiced component, just like for the voiced component. To do so, specify "vocalTract" explicitly (see vignette 2.12.1)
  * soundgen(): the expected range of amplAnchors is now (throwaway, 0), e.g. (-80, 0), and for amplAnchorsGlobal 0 means no change. Values on the old scale will still work (see vignette 2.8)
  * soundgen(): a negative pause (overlap) is allowed between bouts (but not between syllables)
  * soundgen(): attack can be different at the beginning and end of a syllable, e.g. "attackLen = c(50, 100)"
  * getSmoothContour(): proper handling and plotting of anchors that need downsampling, interpolation forced exactly through the specified anchors with interpol = 'approx'
  * segmentFolder(), analyzeFolder(): new argument "htmlPlots" to create an html file with a table of click-to-play plots; new default strategy for saving plots (see "savePlots" argument)
  * analyze(), analyzeFolder(), segment(), segmentFolder(): new argument "res" for proper control of the size and resolution of the output plots


          CHANGES IN SOUNDGEN VERSION 1.1.2 [23-January-2018]
NEW FUNCTIONS:
  * schwa(): estimates expected formant frequencies for a given vocal tract length, deviation of measured formants from the schwa, or formant frequencies in Hz corresponding to given deviations from the schwa
  * getEntropy(): calculates Shannon or Weiner entropy of a vector such as power spectrum

MINOR:
  * soundgen(): very rapid or instantaneous attack is now achievable without adjusting windowLength
  * soundgen(): a new top-level scaling factor formantWidth for simple control of formant bandwidth
  * soundgen(): noiseAnchors are scaled appropriately as syllable length varies due to jitter, while post-syllabic noiseAnchors are not scaled with syllable duration (i.e. the length of post-syllabic aspiration is held constant as syllable length varies)
  * soundgen(): interpol affects the smoothing of mouth anchors
  * analyze(), segment(): streamlined and extended plotting options, fixed a bug in saving plots
  * segment(): fixed a bug that caused pauseLen_sd to always return NA
  * spectrogram(): proper handling of silent or very short input
  * spectrogram(): fixed a bug in denoising routines
  * morph(): fixed a bug with noiseAnchors that are NULL in one sound and another bug caused by changes in duplicated() that were introduced in the new version of r-devel. Thanks to Kurt Hornik for pointing this out


          CHANGES IN SOUNDGEN VERSION 1.1.1 [02-December-2017]
NEW FUNCTIONS:
  * addFormants() for adding or removing formants from an existing sound
  * fade() for adding linear/logarithmic/etc fade-in/out
  * One-click formant picker tool added to soundgen_app()

MINOR:
  * soundgen(): support for discontinuous contours such as pitch jumps, new arguments to soundgen for controlling interpolation between anchors (new arguments: "interpol", "discontThres", "jumpThres")
  * soundgen(): all tempEffects default to 1 and act like scaling factors, a new tempEffect added ("specDep")
  * soundgen(): invalidArgAction propagates through temperature effects, ensuring that "weird" parameter values outside the ranges in permittedValues are processed properly
  * soundgen(): vectorized rolloffNoise
  * soundgen(): slightly modified effects of creakyBreathy hyperparameter
  * soundgen_app(): fixed a bug introduced in soundgen 1.1.0, which caused the app to crash with simplified formant specification
  * Extended and updated vignette on sound generation
  * Miscellaneous small-scale debugging


          CHANGES IN SOUNDGEN VERSION 1.1.0 [19-October-2017]

MAJOR
  * Formant generation is now compatible with standard phonetic models (all-pole or zero-pole models instead of densities of gamma distribution).
  * Unvoiced component is generated with a flat spectrum up to a certain threshold, followed by linear rolloff.
  * An alternative method of synthesizing glottal pulses one by one ("soundgen(glottisAnchors = ...)". Good for vocal fry and, potentially, for integrating alternative models of glottal pulses (future work).
  * Back-compatibility in program syntax is preserved, but presets from version 1.0.0 will sound different. The vignette on sound generation and the preset library are updated accordingly.

MINOR
  * Support for shorthand specification of formants with default amplitudes and bandwidths, e.g. "formants = c(500, 1500, 2500)" or "formants = list(f1 = 800, f2 = c(1500, 2200))".
  * Support for shorthand specification of all anchors in presets and other input to soundgen_app, e.g. "mouthAnchors = c(0, 0, .3, .5)". The expanded format from soundgen 1.0.0 is also supported.
  * Vectorized rolloff and amplitude modulation parameters, allowing them to change dynamically within a vocalization (command-line only; currently not implemented in the Shiny app).
  * Additional components in tempEffects offering more control over stochastic behavior of soundgen() (command-line only).
  * Separate radiation functions for the lips and the nose (when the mouth is closed). The corresponding soundgen() arguments are "lipRad" (replacing "rolloffLip") and "noseRad".
  * Minor debugging and extended capabilities in soundgen_app(), e.g. preview of formant filter, better intergration of spectrogram and spectrum output plots, a simple way to remove the voiced component, etc.
  * Minor debugging elsewhere, notably dB conversion, timing of unvoiced segments in polysyllabic vocalizations in soundgen(), format of the output in analyzeFolder() and segmentFolder(), etc.

NEW FUNCTIONS:
  * flatEnv(): normalizes amplitude envelope dynamically, i.e., keeping loudness constant throughout the sound
  * estimateVTL(): estimates the length of vocal tract based on formant frequencies
  * fart(): a simplified version of soundgen() for simple and rapid generation of a particular type of sounds, like raspberries, ripping noises, etc
  * beat(): generation of percussive noises like drum-like beats, clicks, etc


          RELEASE OF SOUNDGEN VERSION 1.0.0 [04-September-2017]
