This project uses multiple threads to seamlessly play an audio file in small chunks of only milliseconds at a time.
The goal was to architect a system that can continually handle data in a real-time environment while accounting for a slow hardware system.
Used in Development:
* C++
* Multithreading
* Windows Audio System
* Visual Studio Enterprise
* Perforce
Thread-Safe Custom Data Structures:
BufferData:
* Stores data from the audio file.
* Built-in functionality for easy data transfer between buffers.
* Intelligently tracks how it has been used and updates its state accordingly.
Circular Queue:
* Holds commands to be executed at a later time.
* One thread adds a command, then another thread executes it.
Threads:
File Thread:
* Reads data from the audio file into its BufferData using FileSlow API to simulate slower systems.
* Notifies the Coordinator thread when it's filled so that the data can be extracted.
Coordinator Thread:
* Contains two BufferDatas, defined as a front buffer and a back buffer.
* Data is pulled into the back buffer from the File thread, and then the two buffers switch.
* The front buffer pushes data into the WaveBuffers by executing commands from the circular queue.
* Notifies the Playback thread to attempt playing audio when a WaveBuffer is filled.
Playback Thread:
* Manages the 20 WaveBuffer threads.
* Fills the Coordinator's circular queue with WaveBuffers to be filled with data.
* Tracks the current WaveBuffer to be played and plays audio with its data when ready.
* Takes WaveBuffers from the circular queue, cleans them, and adds them to the Coordinator's circular queue.
WaveBuffer Threads:
* Hold 2K worth of audio data in a BufferData to be played.
* Use audio callbacks to readd themselves to the Playback's circular queue.
Kill Thread:
* Tracks the rest of the threads to tell when the program should terminate.
* Ensures that all threads are properly closed with no memory leaks.