Files
ReMixer/include/ReMixer/sound.h
Kayleigh c0c1371823 Add WAV support
Adds WAV support building off of PCMBuffer function

also robodeath 😺
2025-04-20 20:55:16 +02:00

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.
};
}