diff --git a/main.c b/main.c index 143b548..34f2eab 100644 --- a/main.c +++ b/main.c @@ -16,6 +16,12 @@ // Synth //------------------------------------------------------------------------------------ +typedef struct Synth { + OscillatorArray oscillators; + Note current_note; + SynthSound* out_signal; +} Synth; + static int get_semitone_shift_internal(char* root_note, char* target_note) { char* pitch_classes[12] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; @@ -68,38 +74,39 @@ int get_semitone_shift(char* target_note) { return get_semitone_shift_internal("A4", target_note); } -SynthSound note(int semitone, float beats) { - float hz = get_hz_by_semitone(semitone); - float duration = beats * BEAT_DURATION; - +static OscillatorArray init_osc_array() { Oscillator first = { .osc = Square, - .freq = hz + .freq = 440.f }; - Oscillator second = { - .osc = Saw, - .freq = hz + 0.5 - }; + Oscillator* oscArray = malloc(sizeof(Oscillator*) * 1); + oscArray[0] = first; - Oscillator third = { - .osc = Saw, - .freq = hz - 1.f - }; - - Oscillator oscArray[] = { first/*, second, third */}; - OscillatorArray parameters = { + OscillatorArray oscillators = { .array = oscArray, .count = 1 }; - return freq(duration, parameters); + return oscillators; } -SynthSound get_note_sound(Note input) { +SynthSound note(Synth* synth, int semitone, float beats) { + float hz = get_hz_by_semitone(semitone); + float duration = beats * BEAT_DURATION; + + // will change after oscillator starts to be more autonomous + for (size_t i = 0; i < synth->oscillators.count; i++) { + synth->oscillators.array[i].freq = hz; + } + + return freq(duration, synth->oscillators); +} + +SynthSound get_note_sound(Synth* synth, Note input) { float length = 1.f / input.length; int semitone_shift = get_semitone_shift(input.name); - return note(semitone_shift, length); + return note(synth, semitone_shift, length); } //------------------------------------------------------- @@ -137,12 +144,6 @@ size_t detect_note_pressed(Note* note) { return is_pressed; } -typedef struct Synth { - OscillatorArray oscillators; - Note current_note; - SynthSound out_signal; -} Synth; - //------------------------------------------------------------------------------------ // Main //------------------------------------------------------------------------------------ @@ -151,14 +152,22 @@ int main(int argc, char **argv) { InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "SeeSynth - v0.1"); SetTargetFPS(60); - Note current_note = { + //todo: move that variables to Synth declaration + Note g_current_note = { .length = 1, .name = malloc(sizeof(char) * 3) }; - SynthSound sound = { + SynthSound g_sound = { .sample_count = 0 }; + + Synth synth = { + .current_note = g_current_note, + .out_signal = &g_sound, + .oscillators = init_osc_array() + }; + int sound_played_count = 0; float temp_buffer[STREAM_BUFFER_SIZE]; RingBuffer ring_buffer = ring_buffer_init(STREAM_BUFFER_SIZE); @@ -178,25 +187,26 @@ int main(int argc, char **argv) { // Update Audio states //---------------------------------------------------------------------------------- // Fill ring buffer from current sound + SynthSound* sound = synth.out_signal; size_t size_for_buffer = 0; - if (!ring_buffer.is_full && sound.sample_count != sound_played_count) { + if (!ring_buffer.is_full && sound->sample_count != sound_played_count) { write_log("[INFO] IsFull:%d Samples:%zu Played:%zu\n", ring_buffer.is_full, - sound.sample_count, + sound->sample_count, sound_played_count); // how many samples need write size_t size_to_fill = 0; - if ((sound.sample_count - sound_played_count) > ring_buffer.size) { + if ((sound->sample_count - sound_played_count) > ring_buffer.size) { size_to_fill = ring_buffer.size; } else { - size_to_fill = sound.sample_count - sound_played_count; + size_to_fill = sound->sample_count - sound_played_count; } write_log("[INFO] SizeToFill:%zu\n", size_to_fill); for (size_t i = 0; i < size_to_fill; i++) { - temp_buffer[i] = sound.samples[i]; + temp_buffer[i] = sound->samples[i]; } ring_buffer_write(&ring_buffer, temp_buffer, size_to_fill); @@ -213,7 +223,7 @@ int main(int argc, char **argv) { // can try the SetAudioStreamCallback UpdateAudioStream(synth_stream, temp_buffer, size_to_read); // can overwrite the ring buffer to avoid that - if (sound.sample_count == sound_played_count) { + if (sound->sample_count == sound_played_count) { ring_buffer_reset(&ring_buffer); } } @@ -221,8 +231,9 @@ int main(int argc, char **argv) { // Update On Input //---------------------------------------------------------------------------------- + Note current_note = synth.current_note; if (detect_note_pressed(¤t_note)) { - sound = get_note_sound(current_note); + *sound = get_note_sound(&synth, current_note); sound_played_count = 0; write_log("Note played: %s\n", current_note.name); } @@ -248,7 +259,7 @@ int main(int argc, char **argv) { SynthSound* sounds = malloc(sizeof(SynthSound) * note_array.count); for (size_t i = 0; i < note_array.count; i++) { Note note = note_array.notes[i]; - sounds[i] = get_note_sound(note); + sounds[i] = get_note_sound(&synth, note); } SynthSound song = concat_sounds(sounds, note_array.count);