Skip to content

Commit

Permalink
convert most floating types to single-precision
Browse files Browse the repository at this point in the history
fixed #114 -- decided that it's unnecessary to support both types right now, although might be useful to typedef all the types in the API for clarity
  • Loading branch information
anokta committed Nov 26, 2024
1 parent 344d4e5 commit 5f084f1
Show file tree
Hide file tree
Showing 75 changed files with 908 additions and 920 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ musician.SetTempo(/*tempo=*/124.0);
auto instrument = musician.AddInstrument();

// Set the instrument gain to -6dB.
instrument.SetControl(barely::ControlType::kGain, /*value=*/-6.0);
instrument.SetControl(barely::ControlType::kGain, /*value=*/-6.0f);

// Set an instrument note on.
//
// Note pitch is centered around the reference frequency, and measured in octaves. Fractional values
// adjust the frequency logarithmically to maintain perceived pitch intervals in each octave.
constexpr double kC4Pitch = 0.0;
instrument.SetNoteOn(kC4Pitch, /*intensity=*/0.25);
constexpr float kC4Pitch = 0.0f;
instrument.SetNoteOn(kC4Pitch, /*intensity=*/0.25f);

// Check if the instrument note is on.
const bool is_note_on = instrument.IsNoteOn(kC4Pitch); // will return true.
Expand All @@ -58,9 +58,9 @@ performer.SetLooping(/*is_looping=*/true);
auto task = performer.AddTask(
[&]() {
// Set an instrument note on.
instrument.SetNoteOn(/*pitch=*/1.0);
instrument.SetNoteOn(/*pitch=*/1.0f);
// Schedule a one-off task to set the instrument note off after half a beat.
performer.ScheduleOneOffTask([&]() { instrument.SetNoteOff(/*pitch=*/1.0); },
performer.ScheduleOneOffTask([&]() { instrument.SetNoteOff(/*pitch=*/1.0f); },
performer.GetPosition() + 0.5);
},
/*position=*/0.0);
Expand All @@ -83,7 +83,7 @@ musician.Update(timestamp + kLookahead);
//
// Instruments process raw PCM audio samples in a synchronous call. Therefore, `Process` should
// typically be called from an audio thread process callback in real-time audio applications.
double output_samples[1024];
float output_samples[1024];
instrument.Process(output_samples, timestamp);
```
Expand Down
14 changes: 4 additions & 10 deletions examples/common/audio_output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,17 @@ AudioOutput::AudioOutput(int sample_rate, int sample_count) noexcept {
device_config.playback.channels = 1;
device_config.periodSizeInFrames = sample_count;
device_config.sampleRate = sample_rate;
device_config.pUserData = static_cast<void*>(&process_data_);
device_config.pUserData = static_cast<void*>(&process_callback_);
device_config.dataCallback = [](ma_device* device, void* output, const void* /*input*/,
ma_uint32 frame_count) noexcept {
ProcessData& process_data = *static_cast<ProcessData*>(device->pUserData);
if (process_data.callback) {
if (auto& callback = *static_cast<ProcessCallback*>(device->pUserData); callback) {
float* output_buffer = static_cast<float*>(output);
process_data.callback(
{process_data.buffer.begin(), process_data.buffer.begin() + frame_count});
for (int i = 0; i < static_cast<int>(frame_count); ++i) {
output_buffer[i] = static_cast<float>(process_data.buffer[i]);
}
callback({output_buffer, output_buffer + frame_count});
}
};
// Initialize the device.
[[maybe_unused]] const auto result = ma_device_init(nullptr, &device_config, &device_);
assert(result == MA_SUCCESS);
process_data_.buffer.resize(sample_count);
}

AudioOutput::~AudioOutput() noexcept { ma_device_uninit(&device_); }
Expand All @@ -49,7 +43,7 @@ void AudioOutput::Start() {
void AudioOutput::Stop() noexcept { ma_device_stop(&device_); }

void AudioOutput::SetProcessCallback(ProcessCallback process_callback) noexcept {
process_data_.callback = std::move(process_callback);
process_callback_ = std::move(process_callback);
}

} // namespace barely::examples
16 changes: 4 additions & 12 deletions examples/common/audio_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include <functional>
#include <span>
#include <vector>

#include "miniaudio.h"

Expand All @@ -15,7 +14,7 @@ class AudioOutput {
/// Audio process callback signature.
///
/// @param output_samples Span of mono output samples.
using ProcessCallback = std::function<void(std::span<double> output_samples)>;
using ProcessCallback = std::function<void(std::span<float> output_samples)>;

/// Constructs new `AudioOutput`.
///
Expand Down Expand Up @@ -44,18 +43,11 @@ class AudioOutput {
void SetProcessCallback(ProcessCallback process_callback) noexcept;

private:
// Process data.
struct ProcessData {
// Buffer.
std::vector<double> buffer;

// Callback.
ProcessCallback callback = nullptr;
};
ProcessData process_data_;

// Audio device.
ma_device device_;

// Process callback.
ProcessCallback process_callback_ = nullptr;
};

} // namespace barely::examples
Expand Down
2 changes: 1 addition & 1 deletion examples/common/wav_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace barely::examples {

const std::vector<double>& WavFile::GetData() const noexcept { return data_; }
const std::vector<float>& WavFile::GetData() const noexcept { return data_; }

int WavFile::GetChannelCount() const noexcept { return channel_count_; }

Expand Down
4 changes: 2 additions & 2 deletions examples/common/wav_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class WavFile {
/// Returns the audio data.
///
/// @return Audio data.
[[nodiscard]] const std::vector<double>& GetData() const noexcept;
[[nodiscard]] const std::vector<float>& GetData() const noexcept;

/// Returns the number of audio channels.
///
Expand All @@ -38,7 +38,7 @@ class WavFile {
int sample_rate_ = 0;

// Audio data.
std::vector<double> data_;
std::vector<float> data_;
};

} // namespace barely::examples
Expand Down
20 changes: 10 additions & 10 deletions examples/demo/arpeggiator_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,31 @@ constexpr int kSampleCount = 256;
constexpr double kLookahead = 0.1;

// Arpeggiator settings.
constexpr double kGain = -18.0;
constexpr float kGain = -18.0f;
constexpr OscillatorShape kOscillatorShape = OscillatorShape::kSquare;
constexpr double kAttack = 0.0;
constexpr double kRelease = 0.05;
constexpr float kAttack = 0.0f;
constexpr float kRelease = 0.05f;
constexpr int kVoiceCount = 16;

constexpr double kInitialGateRatio = 0.5;
constexpr float kInitialGateRatio = 0.5f;
constexpr double kInitialRate = 4.0;
constexpr double kInitialTempo = 100.0;
constexpr ArpeggiatorStyle kInitialStyle = ArpeggiatorStyle::kUp;

// Note settings.
constexpr std::array<char, 13> kOctaveKeys = {'A', 'W', 'S', 'E', 'D', 'F', 'T',
'G', 'Y', 'H', 'U', 'J', 'K'};
constexpr double kRootPitch = 0.0;
constexpr float kRootPitch = 0.0f;
constexpr int kMaxOctaveShift = 4;

// Returns the pitch for a given `key`.
std::optional<double> PitchFromKey(int octave_shift, const InputManager::Key& key) {
std::optional<float> PitchFromKey(int octave_shift, const InputManager::Key& key) {
const auto it = std::find(kOctaveKeys.begin(), kOctaveKeys.end(), std::toupper(key));
if (it == kOctaveKeys.end()) {
return std::nullopt;
}
return kRootPitch + static_cast<double>(octave_shift) +
static_cast<double>(std::distance(kOctaveKeys.begin(), it)) / 12.0;
return kRootPitch + static_cast<float>(octave_shift) +
static_cast<float>(std::distance(kOctaveKeys.begin(), it)) / 12.0f;
}

} // namespace
Expand All @@ -80,7 +80,7 @@ int main(int /*argc*/, char* /*argv*/[]) {
instrument.SetControl(ControlType::kVoiceCount, kVoiceCount);

instrument.SetNoteOnEvent(
[](double pitch, double /*intensity*/) { ConsoleLog() << "Note(" << pitch << ")"; });
[](float pitch, float /*intensity*/) { ConsoleLog() << "Note(" << pitch << ")"; });

Arpeggiator arpeggiator(musician);
arpeggiator.SetInstrument(instrument);
Expand All @@ -89,7 +89,7 @@ int main(int /*argc*/, char* /*argv*/[]) {
arpeggiator.SetStyle(kInitialStyle);

// Audio process callback.
audio_output.SetProcessCallback([&](std::span<double> output_samples) {
audio_output.SetProcessCallback([&](std::span<float> output_samples) {
instrument.Process(output_samples, audio_clock.GetTimestamp());
audio_clock.Update(static_cast<int>(output_samples.size()));
});
Expand Down
28 changes: 14 additions & 14 deletions examples/demo/instrument_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,26 @@ constexpr int kSampleRate = 48000;
constexpr int kSampleCount = 256;

// Instrument settings.
constexpr double kGain = -18.0;
constexpr float kGain = -18.0f;
constexpr OscillatorShape kOscillatorShape = OscillatorShape::kSaw;
constexpr double kAttack = 0.05;
constexpr double kRelease = 0.125;
constexpr float kAttack = 0.05f;
constexpr float kRelease = 0.125f;
constexpr int kVoiceCount = 16;

// Note settings.
constexpr std::array<char, 13> kOctaveKeys = {'A', 'W', 'S', 'E', 'D', 'F', 'T',
'G', 'Y', 'H', 'U', 'J', 'K'};
constexpr double kRootPitch = 0.0;
constexpr float kRootPitch = 0.0f;
constexpr int kMaxOctaveShift = 4;

// Returns the pitch for a given `key`.
std::optional<double> PitchFromKey(int octave_shift, const InputManager::Key& key) {
std::optional<float> PitchFromKey(int octave_shift, const InputManager::Key& key) {
const auto it = std::find(kOctaveKeys.begin(), kOctaveKeys.end(), std::toupper(key));
if (it == kOctaveKeys.end()) {
return std::nullopt;
}
return kRootPitch + static_cast<double>(octave_shift) +
static_cast<double>(std::distance(kOctaveKeys.begin(), it)) / 12.0;
return kRootPitch + static_cast<float>(octave_shift) +
static_cast<float>(std::distance(kOctaveKeys.begin(), it)) / 12.0f;
}

} // namespace
Expand All @@ -65,18 +65,18 @@ int main(int /*argc*/, char* /*argv*/[]) {
instrument.SetControl(ControlType::kRelease, kRelease);
instrument.SetControl(ControlType::kVoiceCount, kVoiceCount);

instrument.SetNoteOnEvent([](double pitch, double intensity) {
instrument.SetNoteOnEvent([](float pitch, float intensity) {
ConsoleLog() << "NoteOn(" << pitch << ", " << intensity << ")";
});
instrument.SetNoteOffEvent([](double pitch) { ConsoleLog() << "NoteOff(" << pitch << ") "; });
instrument.SetNoteOffEvent([](float pitch) { ConsoleLog() << "NoteOff(" << pitch << ") "; });

// Audio process callback.
audio_output.SetProcessCallback([&](std::span<double> output_samples) {
audio_output.SetProcessCallback([&](std::span<float> output_samples) {
instrument.Process(output_samples, /*timestamp=*/0.0);
});

// Key down callback.
double intensity = 1.0;
float intensity = 1.0f;
int octave_shift = 0;
bool quit = false;
const auto key_down_callback = [&](const InputManager::Key& key) {
Expand All @@ -102,11 +102,11 @@ int main(int /*argc*/, char* /*argv*/[]) {
if (upper_key == 'C' || upper_key == 'V') {
// Change intensity.
if (upper_key == 'C') {
intensity -= 0.25;
intensity -= 0.25f;
} else {
intensity += 0.25;
intensity += 0.25f;
}
intensity = std::clamp(intensity, 0.0, 1.0);
intensity = std::clamp(intensity, 0.0f, 1.0f);
ConsoleLog() << "Note intensity set to " << intensity;
return;
}
Expand Down
14 changes: 7 additions & 7 deletions examples/demo/metronome_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ constexpr double kLookahead = 0.1;

// Metronome settings.
constexpr OscillatorShape kOscillatorShape = OscillatorShape::kSquare;
constexpr double kGain = -12.0;
constexpr double kAttack = 0.0;
constexpr double kRelease = 0.05;
constexpr float kGain = -12.0f;
constexpr float kAttack = 0.0f;
constexpr float kRelease = 0.05f;
constexpr int kVoiceCount = 1;

constexpr double kBarPitch = 1.0;
constexpr double kBeatPitch = 0.0;
constexpr float kBarPitch = 1.0f;
constexpr float kBeatPitch = 0.0f;

constexpr int kBeatCount = 4;
constexpr double kInitialTempo = 120.0;
Expand Down Expand Up @@ -68,13 +68,13 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) {
const int current_bar = (beat / kBeatCount) + 1;
const int current_beat = (beat % kBeatCount) + 1;
ConsoleLog() << "Tick " << current_bar << "." << current_beat;
const double pitch = current_beat == 1 ? kBarPitch : kBeatPitch;
const float pitch = current_beat == 1 ? kBarPitch : kBeatPitch;
instrument.SetNoteOn(pitch);
instrument.SetNoteOff(pitch);
});

// Audio process callback.
const auto process_callback = [&](std::span<double> output_samples) {
const auto process_callback = [&](std::span<float> output_samples) {
instrument.Process(output_samples, audio_clock.GetTimestamp());
audio_clock.Update(static_cast<int>(output_samples.size()));
};
Expand Down
20 changes: 10 additions & 10 deletions examples/demo/midi_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ constexpr double kLookahead = 0.1;

// Instrument settings.
constexpr OscillatorShape kInstrumentOscillatorShape = OscillatorShape::kSquare;
constexpr double kInstrumentEnvelopeAttack = 0.0;
constexpr double kInstrumentEnvelopeRelease = 0.2;
constexpr float kInstrumentEnvelopeAttack = 0.0f;
constexpr float kInstrumentEnvelopeRelease = 0.2f;
constexpr int kInstrumentVoiceCount = 16;
constexpr double kInstrumentGain = -20.0;
constexpr float kInstrumentGain = -20.0f;

// Midi file name.
constexpr char kMidiFileName[] = "midi/sample.mid";
Expand All @@ -61,8 +61,8 @@ bool BuildScore(const smf::MidiEventList& midi_events, int ticks_per_beat,
if (midi_event.isNoteOn()) {
const double position = get_position_fn(midi_event.tick);
const double duration = get_position_fn(midi_event.getTickDuration());
const double pitch = static_cast<double>(midi_event.getKeyNumber() - 60) / 12.0;
const double intensity = static_cast<double>(midi_event.getVelocity()) / 127.0;
const float pitch = static_cast<float>(midi_event.getKeyNumber() - 60) / 12.0f;
const float intensity = static_cast<float>(midi_event.getVelocity()) / 127.0f;
performer.ScheduleOneOffTask(
[&instrument, pitch, intensity]() mutable { instrument.SetNoteOn(pitch, intensity); },
position);
Expand Down Expand Up @@ -112,11 +112,11 @@ int main(int /*argc*/, char* argv[]) {
}
// Set the instrument settings.
const auto track_index = tracks.size() + 1;
instrument.SetNoteOnEvent([track_index](double pitch, double intensity) {
instrument.SetNoteOnEvent([track_index](float pitch, float intensity) {
ConsoleLog() << "MIDI track #" << track_index << ": NoteOn(" << pitch << ", " << intensity
<< ")";
});
instrument.SetNoteOffEvent([track_index](double pitch) {
instrument.SetNoteOffEvent([track_index](float pitch) {
ConsoleLog() << "MIDI track #" << track_index << ": NoteOff(" << pitch << ")";
});
instrument.SetControl(ControlType::kGain, kInstrumentGain);
Expand All @@ -128,9 +128,9 @@ int main(int /*argc*/, char* argv[]) {
ConsoleLog() << "Number of active MIDI tracks: " << tracks.size();

// Audio process callback.
std::vector<double> mix_buffer(kSampleCount);
const auto process_callback = [&](std::span<double> output_samples) {
std::fill_n(output_samples.begin(), kSampleCount, 0.0);
std::vector<float> mix_buffer(kSampleCount);
const auto process_callback = [&](std::span<float> output_samples) {
std::fill_n(output_samples.begin(), kSampleCount, 0.0f);
for (auto& [instrument, performer] : tracks) {
instrument.Process(mix_buffer, clock.GetTimestamp());
std::transform(mix_buffer.begin(), mix_buffer.end(), output_samples.begin(),
Expand Down
Loading

0 comments on commit 5f084f1

Please sign in to comment.