176 lines
8.5 KiB
C++
176 lines
8.5 KiB
C++
/// ReMixer
|
|
/// A Public Domain C++ Audio Playback Library
|
|
/// By william @ RedactedSoftware. Thanks to Dawsh & Maxine.
|
|
/// (c) 2024 Redacted Software
|
|
/// This work is explicitly dedicated to the public domain, for the hopeful betterment of the software industry.
|
|
|
|
/// @file sound.h
|
|
/// @desc This class contains and manipulates sound data.
|
|
/// @edit 2024-08-29
|
|
|
|
#pragma once
|
|
#include <vector>
|
|
#include <pulse/pulseaudio.h>
|
|
#include <pulse/simple.h>
|
|
#include <filesystem>
|
|
#include <ReMixer/stream.h>
|
|
#include <ReMixer/ReMixer.h>
|
|
#include <iterator>
|
|
#include <vorbis/vorbisfile.h>
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
int mix(int a, int b);
|
|
|
|
namespace ReMixer {
|
|
|
|
// TODO: Implement support for loading Linear-PCM if necessary.
|
|
// TODO: Correctly handle different 'sample-depths'. PCM Samples can be encoded at 8, 16, 20, or 24 bits-per-sample.
|
|
|
|
/// The sound class contains a raw audio data buffer in Pulse-Code Modulated form.
|
|
class Sound {
|
|
public:
|
|
|
|
/// The default constructor for a Sound object is intentionally left undefined.
|
|
/// It is intended that you use the static constructors below to load Sound objects.
|
|
Sound() = default;
|
|
|
|
/// Returns a Sound object loaded from a OGG Vorbis file, usually with an .ogg extension.
|
|
/// The sample rate and channel mode will be read from the vorbisfile header.
|
|
/// @param file_name The full path relative to the executable in which the file is located.
|
|
/// @see https://en.wikipedia.org/wiki/Vorbis
|
|
/// @see LoadOGGVorbisFile().
|
|
static Sound FromOGGVorbisFile(const std::filesystem::path &file_name);
|
|
|
|
/// Returns a Sound object loaded from a WAV file, usually with a .wav or .wave extension.
|
|
/// The sample rate and channel mode will be read from the WAV header.
|
|
/// @param file_name The full path relative to the executable in which the file is located.
|
|
/// @see https://en.wikipedia.org/wiki/WAV
|
|
/// @see LoadWAVFile().
|
|
static Sound FromWAVFile(const std::filesystem::path &file_name);
|
|
|
|
/// Returns a sound object loaded from a file containing raw PCM sound data in binary form.
|
|
/// @param file_name The full path relative to the executable in which the file is located.
|
|
/// @param sampleRate A uint that indicates the samples-per-second of the sound data.
|
|
/// @param streamMode An enum representing the number of channels.
|
|
/// @see https://en.wikipedia.org/wiki/Pulse-code_modulation.
|
|
/// @see FromPCMBuffer(), LoadPCMFile(), enum StreamMode.
|
|
static Sound FromPCMFile(const std::filesystem::path &file_name, uint sampleRate = 44.1_kHz,
|
|
StreamMode streamMode = StreamMode::STEREO);
|
|
|
|
/// Returns a sound object loaded from a byte-buffer containing raw PCM sound data.
|
|
/// @param buffer The byte buffer that will be copied into this sound object.
|
|
/// @param sampleRate A uint that indicates the samples-per-second of the sound data.
|
|
/// @param streamMode An enum representing the number of channels.
|
|
/// @see https://en.wikipedia.org/wiki/Pulse-code_modulation.
|
|
static Sound
|
|
FromPCMBuffer(std::vector<char> buffer, uint sampleRate = 44.1_kHz, StreamMode streamMode = StreamMode::STEREO);
|
|
|
|
/// Returns a single-channel sound object generated from a trigonometric sine function.
|
|
/// @see https://en.wikipedia.org/wiki/Sine_wave
|
|
static Sound FromSineWave(float length, float wavelength, float amplitude, float phase);
|
|
|
|
/// Returns a single-channel sound object generated from a sawtooth wave function.
|
|
/// Sawtooth waves of constant period contain odd and even harmonics that decrease at -6 dB / octave.
|
|
/// @see https://en.wikipedia.org/wiki/Sawtooth_wave
|
|
static Sound FromSawtoothWave(float length, float wavelength, float amplitude, float phase);
|
|
|
|
/// Returns a single-channel sound object generated from a triangle wave function.
|
|
/// Triangle waves contain odd harmonics that decrease at -12 dB / octave.
|
|
/// @see https://en.wikipedia.org/wiki/Triangle_wave
|
|
static Sound FromTriangleWave(float length, float wavelength, float amplitude, float phase);
|
|
|
|
/// Returns a single-channel sound object generated from a square wave function.
|
|
/// Square waves of constant period contain odd harmonics that decrease at -6 dB / octave.
|
|
/// @see https://en.wikipedia.org/wiki/Square_wave
|
|
static Sound FromSquareWave(float length, float wavelength, float amplitude, float phase);
|
|
|
|
|
|
static Sound FromNoise(float length, float amplitude = 1.f);
|
|
|
|
/// Fills this sound instance with data from a file encoded with OGG vorbis, usually with an .ogg extension.
|
|
/// @param file_name The full path relative to the executable in which the file is located.
|
|
/// @see https://en.wikipedia.org/wiki/Vorbis
|
|
/// @see FromOGGVorbisFile().
|
|
void LoadOGGVorbisFile(const std::filesystem::path &file_name);
|
|
|
|
/// Fills this sound instance with data from a file encoded with WAV, usually with a .wav or .wave extension.
|
|
/// @param file_name The full path relative to the executable in which the file is located.
|
|
/// @see https://en.wikipedia.org/wiki/WAV
|
|
/// @see FromWAVFile().
|
|
void LoadWAVFile(const std::filesystem::path &file_name);
|
|
|
|
/// Fills this sound instance with data from a file containing raw PCM sound data.
|
|
/// @param file_name The full path relative to the executable in which the file is located.
|
|
/// @param sampleRate A uint that indicates the samples-per-second of the sound data.
|
|
/// @param streamMode An enum representing the number of channels.
|
|
/// @see https://en.wikipedia.org/wiki/Pulse-code_modulation.
|
|
void LoadPCMFile(const std::filesystem::path &file_name, uint sampleRate = 44.1_kHz,
|
|
StreamMode streamMode = StreamMode::STEREO);
|
|
|
|
/// Fills this sound instance with data from a byte-buffer containing raw PCM sound data.
|
|
/// @param buffer The byte buffer that will be copied into this sound object.
|
|
/// @param sampleRate A uint that indicates the samples-per-second of the sound data.
|
|
/// @param streamMode An enum representing the number of channels.
|
|
/// @see https://en.wikipedia.org/wiki/Pulse-code_modulation.
|
|
void
|
|
LoadPCMBuffer(std::vector<char> buffer, uint sampleRate = 44.1_kHz, StreamMode streamMode = StreamMode::STEREO);
|
|
|
|
void LoadSineWave(float length, float wavelength, float amplitude, float phase);
|
|
void LoadSawtoothWave(float length, float wavelength, float amplitude, float phase);
|
|
void LoadTriangleWave(float length, float wavelength, float amplitude, float phase);
|
|
void LoadSquareWave(float length, float wavelength, float amplitude, float phase);
|
|
|
|
void LoadNoise(float length, float amplitude = 1.f);
|
|
|
|
/// Returns the sample count of the sound.
|
|
uint SampleCount() const;;
|
|
|
|
/// Returns the amount of bytes the sounds' data occupies.
|
|
uint DataSizeInBytes() const;
|
|
|
|
/// Returns the samples-per-second of this sound.
|
|
uint SampleRate() const;
|
|
|
|
/// Returns an enumeration indicating the channel mode of the sound resource (MONO, STEREO).
|
|
StreamMode GetStreamMode() const;
|
|
|
|
/// Returns the number of separate channels this sound resource contains.
|
|
uint Channels() const;
|
|
|
|
/// Returns the time length, in seconds, of this sound resource.
|
|
float PlaybackLength();
|
|
|
|
/// Returns a pointer to the beginning of the audio data buffer.
|
|
char *ptr() { return audio_data.data(); }
|
|
|
|
/// Same as above, but const-qualified for simple reads into the buffer.
|
|
[[nodiscard]] const char *ptr() const { return audio_data.data(); }
|
|
|
|
/// Returns a particular sample at a given index.
|
|
char &At(uint index);
|
|
|
|
/// Returns a particular sample at a given index.
|
|
[[nodiscard]] char At(uint index) const;
|
|
|
|
/// Mixing Test Operator
|
|
Sound operator+(const Sound &rhs) const;
|
|
|
|
private:
|
|
uint sample_rate;
|
|
std::vector<char> audio_data;
|
|
StreamMode stream_mode;
|
|
};
|
|
|
|
/// Class that holds a short sound that can fit in memory and requires no latency. (i.e. footsteps or gun shots).
|
|
class SFX : public Sound {
|
|
// TODO: Implement SFX class.
|
|
};
|
|
|
|
/// Music class is for longer sounds that should be streamed in from disk.
|
|
class Music : public Sound {
|
|
// TODO: Implement Music class.
|
|
};
|
|
}
|
|
|