The core of this project is an audio pipeline separated into 3 parts:
- Fetching samples -> Processing (applying settings and effects) -> Outputting modified samples
Above this pipeline exists a GUI which interacts with the Processing by changing its settings and visualizing its outputs.
Reads actual data from the audio file.
Exposes metadata about the file - sample rate and channel count.
Is created upon successful decoding of an audio file and creates an abstraction for the input. Can be consumed by calling ReadFrame(int size) at a desired pace.
Makes sure that all samples are in a set size of frames.
It also enforces the IDisposable contract and is therefore intended to cease to exist when the connected audio stops playing or is aborted.
The core class of the processing stage. Runs the entire pipeline.
Is created with the AudioStream and shares its lifespan with it.
Runs processes that consume data from a stream and add it to a player in parallel.
Uses and IFftProcessor to decompose sound and extract information about frequencies.
From there it exports to the IFreqDataReceiver if necessary.
Applies all plugin effects, volume changes, eq settings to the audio samples.
Processed samples get sent to the IAudioPlayer.
Receives samples from the audio engine and buffers them in order to output them at a steady pace.
Must be fed enough samples to prevent skips or distortion.
Runs the GUI logic and makes calls to the AudioEngine based on requests from Views.
Implements the IFreqDataReceiver interface and accepts data from the AudioEngine.
It further processes this data so that the desired Views can render it straight away.
Draws the current state of the frequency graph every couple of miliseconds.
Plugins get instantiated from a set folder via reflection thanks to the IAudioPlugin interface.
The 3rd party developer has access to normalized PCM samples and can edit them freely.
NAudioIAudioReader and playing PCM samples in IAudioPlayer.Math.NETIFftProcessor wraps around its Fourier transform to create frame-sized transformations.Terminal.GuiThe project is laid out in such a way that making it work cross-platform should be straightforward and painless.
Readers/Players are abstracted behind an interface. Linux/macOS support could work by just adding some more dependecies that decode audio files and connect to audio sinks.