From c16447f30e1899b3bf3b5a0cb69b6dc3d9706c87 Mon Sep 17 00:00:00 2001 From: HiveBeats Date: Wed, 9 Aug 2023 23:13:08 +0400 Subject: [PATCH] wip: continious sound --- inc/Adder.h | 2 +- inc/Settings.h | 3 ++- src/ADSR.cpp | 4 ++-- src/Application.cpp | 56 +++++++++++++++++++++++++-------------------- src/Renderer.cpp | 2 +- src/Synth.cpp | 2 +- 6 files changed, 38 insertions(+), 31 deletions(-) diff --git a/inc/Adder.h b/inc/Adder.h index 23abd87..fbf0114 100644 --- a/inc/Adder.h +++ b/inc/Adder.h @@ -9,7 +9,7 @@ struct Adder { static std::vector& SumOscillators(const std::vector& oscillators, float duration) { - size_t sample_count = (size_t)(duration * SAMPLE_RATE); + size_t sample_count = (size_t)(1.f/FPS * SAMPLE_RATE); std::vector* output = new std::vector(); output->reserve(sample_count); diff --git a/inc/Settings.h b/inc/Settings.h index dbf08e5..4317479 100644 --- a/inc/Settings.h +++ b/inc/Settings.h @@ -6,7 +6,8 @@ #define PITCH_STANDARD 440.f #define VOLUME 0.5f #define ATTACK_MS 100.f -#define STREAM_BUFFER_SIZE 4096 +#define STREAM_BUFFER_SIZE 1024 +#define FPS 60 #define SYNTH_PI 3.1415926535f #define SYNTH_VOLUME 0.5f diff --git a/src/ADSR.cpp b/src/ADSR.cpp index 55054cd..f670c13 100644 --- a/src/ADSR.cpp +++ b/src/ADSR.cpp @@ -3,7 +3,7 @@ #include "Logger.h" ADSR::ADSR(/* args */) { - m_parameters.attack_time = 0.025f; + m_parameters.attack_time = 1.f; m_parameters.decay_time = 0.3f; m_parameters.sustain_level = 0.6f; m_parameters.release_time = 1.0f; @@ -35,7 +35,7 @@ void ADSR::process_sample(float* sample, std::size_t attack_samples, set_state(attack_samples, decay_samples, release_samples); if (m_state == Attack) { - (*sample) = (float)(1.f / attack_samples) * m_counter; + (*sample) = (*sample) * ((float)(1.f / attack_samples) * m_counter); } else if (m_state == Decay) { } m_counter++; diff --git a/src/Application.cpp b/src/Application.cpp index 2349fbb..1cbda5e 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -39,7 +39,7 @@ void Application::init_synth() { // todo: move that variables to Synth declaration std::string* nameString = new std::string(std::string(new char[3])); m_current_note = new Note{.length = 1, .name = (*nameString)}; - + m_current_note->name.assign("G4"); // todo: move somewhere in initialization std::vector oscillators = m_synth.GetOscillators(); m_synth_gui_state.oscillators.reserve(oscillators.size()); @@ -91,55 +91,61 @@ std::size_t Application::detect_note_pressed(Note* note) { // Update On Input void Application::update_on_note_input() { - if (detect_note_pressed(m_current_note)) { + detect_note_pressed(m_current_note); + // if (detect_note_pressed(m_current_note)) { m_synth.ProduceNoteSound((*m_current_note)); - m_sound_played_count = 0; + //m_sound_played_count = 0; write_log("Note played: %s\n", m_current_note->name.c_str()); - } + //} } // Play ring-buffered audio void Application::play_buffered_audio() { - if (IsAudioStreamProcessed(m_synth_stream) && !m_ring_buffer->IsEmpty()) { - std::size_t size_to_read = m_ring_buffer->GetSize(); - + std::size_t size_to_read = m_ring_buffer->GetSize(); + size_t sample_count = (size_t)(1.f/FPS * SAMPLE_RATE); + if (IsAudioStreamProcessed(m_synth_stream)) { write_log("Samples to play:%zu \n", size_to_read); // todo: try to start reading directly from ring buffer, avoiding // temp_buffer - m_ring_buffer->Read(m_temp_buffer, size_to_read); + //todo: can be optimized to only move pointers, without the usage of temp buffer + // can try the SetAudioStreamCallback - UpdateAudioStream(m_synth_stream, m_temp_buffer, size_to_read); + UpdateAudioStream(m_synth_stream, m_temp_buffer, sample_count); // can overwrite the ring buffer to avoid that - if (m_synth.GetOutSignal().size() == m_sound_played_count) { - m_ring_buffer->Reset(); - } + + // if (m_synth.GetOutSignal().size() == m_sound_played_count) { + // m_ring_buffer->Reset(); + // } + } + m_ring_buffer->Read(m_temp_buffer, sample_count); + m_ring_buffer->Reset(); + if (m_ring_buffer->IsFull() || m_ring_buffer->IsEmpty()) { } } // Fill ring buffer from current sound void Application::fill_audio_buffer() { - if (!m_ring_buffer->IsFull() && + if (!m_ring_buffer->IsFull() && m_synth.GetOutSignal().size() != m_sound_played_count) { write_log("[INFO] IsFull:%d Samples:%zu Played:%d\n", m_ring_buffer->IsFull(), m_synth.GetOutSignal().size(), m_sound_played_count); // how many samples need write - std::size_t size_to_fill = 0; - - if ((m_synth.GetOutSignal().size() - m_sound_played_count) > - m_ring_buffer->GetCapacity()) { - size_to_fill = m_ring_buffer->GetCapacity(); - } else { - size_to_fill = m_synth.GetOutSignal().size() - m_sound_played_count; - } + std::size_t size_to_fill = m_ring_buffer->GetCapacity() - m_synth.GetOutSignal().size(); + // if ((m_synth.GetOutSignal().size() - m_sound_played_count) > + // m_ring_buffer->GetCapacity()) { + + // } else { + // size_to_fill = m_synth.GetOutSignal().size() - m_sound_played_count; + // } write_log("[INFO] SizeToFill:%zu\n", size_to_fill); - for (size_t i = 0; i < size_to_fill; i++) { - m_temp_buffer[i] = m_synth.GetOutSignal()[i]; - } + // for (size_t i = 0; i < size_to_fill; i++) { + // m_temp_buffer[i] = m_synth.GetOutSignal()[i]; + // } - m_ring_buffer->Write(m_temp_buffer, size_to_fill); + m_ring_buffer->Write((float*)m_synth.GetOutSignal().data(), size_to_fill); m_sound_played_count += size_to_fill; } } diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 32a8748..a73e016 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -6,7 +6,7 @@ Renderer::Renderer(/* args */) { InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "SeeSynth - v0.2"); - SetTargetFPS(60); + SetTargetFPS(FPS); } Renderer::~Renderer() {} diff --git a/src/Synth.cpp b/src/Synth.cpp index 4df2755..03c0b03 100644 --- a/src/Synth.cpp +++ b/src/Synth.cpp @@ -31,7 +31,7 @@ std::vector& Synth::get_note(int semitone, float beats) { void Synth::apply_effects() { for (Effect* effect : m_effects) { // maybe not here - effect->RetriggerState(); + //effect->RetriggerState(); effect->Process(m_out_signal); } }