4 Commits

Author SHA1 Message Date
0eb203f9f4 feat: configure debugging 2023-06-17 19:37:18 +04:00
d7f4538418 fix(note): semitone shift overflow 2023-06-17 19:37:02 +04:00
0cdac55d27 wip: playing sounds on keypress 2023-06-17 16:33:38 +04:00
10bf0c6a06 feat: detect note pressed 2023-06-17 16:03:07 +04:00
4 changed files with 131 additions and 15 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
/bin /bin
.DS_Store .DS_Store
/Debug/ /Debug/
*.wav *.wav
*.dSYM

View File

@@ -4,5 +4,6 @@
], ],
"files.associations": { "files.associations": {
"algorithm": "c" "algorithm": "c"
} },
"FSharp.suggestGitignore": false,
} }

32
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,32 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: clang сборка активного файла",
"command": "/usr/bin/clang",
"args": [
"-fcolor-diagnostics",
"-fansi-escape-codes",
"-g",
"${file}",
"${fileDirname}/parser.c",
"-lm",
"-lraylib",
"-o",
"${fileDirname}/bin/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Задача создана отладчиком."
}
],
"version": "2.0.0"
}

108
main.c
View File

@@ -14,6 +14,7 @@
#define ATTACK_MS 100.f #define ATTACK_MS 100.f
#define SYNTH_PI 3.1415926535f #define SYNTH_PI 3.1415926535f
#define SYNTH_VOLUME 0.5f
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// General SynthSound // General SynthSound
@@ -24,6 +25,9 @@ typedef struct SynthSound {
size_t sample_count; size_t sample_count;
} SynthSound; } SynthSound;
float synth_buffer[1024];
SynthSound synth_sound;
// frees the original sounds // frees the original sounds
SynthSound concat_sounds(SynthSound* sounds, size_t count) { SynthSound concat_sounds(SynthSound* sounds, size_t count) {
size_t total_count = 0; size_t total_count = 0;
@@ -180,6 +184,20 @@ static SynthSound freq(float duration, OscillatorParameterList osc) {
} }
*/ */
// if (samples.sample_count > 1024) {
// samples.sample_count = 1024;
// }
// //todo: move to somewhere
// for (size_t i = 0; i < 1024; i++) {
// synth_sound.samples[i] = 0.0f;
// }
// for (size_t i = 0; i < samples.sample_count; i++) {
// synth_sound.samples[i] = output[i];
// }
// synth_sound.sample_count = samples.sample_count;
// return zipped array // return zipped array
SynthSound res = { SynthSound res = {
.samples = output, .samples = output,
@@ -216,7 +234,7 @@ static SynthSound get_attack_samples() {
// Synth // Synth
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
static size_t get_semitone_shift_internal(char* root_note, char* target_note) { static int get_semitone_shift_internal(char* root_note, char* target_note) {
char* pitch_classes[12] = char* pitch_classes[12] =
{ "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
@@ -260,21 +278,21 @@ static size_t get_semitone_shift_internal(char* root_note, char* target_note) {
(target_pitch_class - root_pitch_class); (target_pitch_class - root_pitch_class);
} }
static float get_hz_by_semitone(size_t semitone) { static float get_hz_by_semitone(int semitone) {
return PITCH_STANDARD * powf(powf(2.f, (1.f / 12.f)), semitone); return PITCH_STANDARD * powf(powf(2.f, (1.f / 12.f)), semitone);
} }
size_t get_semitone_shift(char* target_note) { int get_semitone_shift(char* target_note) {
return get_semitone_shift_internal("A4", target_note); return get_semitone_shift_internal("A4", target_note);
} }
SynthSound note(size_t semitone, float beats) { SynthSound note(int semitone, float beats) {
float hz = get_hz_by_semitone(semitone); float hz = get_hz_by_semitone(semitone);
float duration = beats * BEAT_DURATION; float duration = beats * BEAT_DURATION;
OscillatorParameter first = { OscillatorParameter first = {
.osc = Saw, .osc = Saw,
.freq = hz/4.f .freq = hz
}; };
OscillatorParameter second = { OscillatorParameter second = {
@@ -287,10 +305,10 @@ SynthSound note(size_t semitone, float beats) {
.freq = hz - 1.f .freq = hz - 1.f
}; };
OscillatorParameter oscArray[] = { first, second, third }; OscillatorParameter oscArray[] = { first/*, second, third */};
OscillatorParameterList parameters = { OscillatorParameterList parameters = {
.array = oscArray, .array = oscArray,
.count = 3 .count = 1
}; };
return freq(duration, parameters); return freq(duration, parameters);
@@ -298,7 +316,7 @@ SynthSound note(size_t semitone, float beats) {
SynthSound get_note_sound(Note input) { SynthSound get_note_sound(Note input) {
float length = 1.f / input.length; float length = 1.f / input.length;
size_t semitone_shift = get_semitone_shift(input.name); int semitone_shift = get_semitone_shift(input.name);
return note(semitone_shift, length); return note(semitone_shift, length);
} }
@@ -376,23 +394,84 @@ void pack(uint16_t* d, size_t length) {
write_file("output.wav", buffer, fileSize); write_file("output.wav", buffer, fileSize);
} }
size_t detect_note_pressed(Note* note) {
size_t is_pressed = 0;
note->length = 16;
if (IsKeyPressed(KEY_A)) {
strcpy(note->name, "A4");
is_pressed = 1;
}
if (IsKeyPressed(KEY_B)) {
strcpy(note->name, "B4");
is_pressed = 1;
}
if (IsKeyPressed(KEY_C)) {
strcpy(note->name, "C4");
is_pressed = 1;
}
if (IsKeyPressed(KEY_D)) {
strcpy(note->name, "D4");
is_pressed = 1;
}
if (IsKeyPressed(KEY_E)) {
strcpy(note->name, "E4");
is_pressed = 1;
}
if (IsKeyPressed(KEY_F)) {
strcpy(note->name, "F4");
is_pressed = 1;
}
if (IsKeyPressed(KEY_G)) {
strcpy(note->name, "G4");
is_pressed = 1;
}
return is_pressed;
}
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Main // Main
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
int main(int argc, char **argv) { int main(int argc, char **argv) {
const size_t width = 1280; const size_t width = 640;
const size_t height = 720; const size_t height = 480;
InitWindow(width, height, "SeeSynth - v0.1"); InitWindow(width, height, "SeeSynth - v0.1");
//SetTargetFPS(60); SetTargetFPS(120);
Note current_note = {
.length = 1,
.name = malloc(sizeof(char) * 3)
};
synth_sound = (SynthSound){.sample_count = 1024, .samples = synth_buffer};
InitAudioDevice();
SetMasterVolume(SYNTH_VOLUME);
AudioStream synth_stream = LoadAudioStream(SAMPLE_RATE, sizeof(float) * 8, 1);//float*8
SetAudioStreamVolume(synth_stream, 0.5f);
PlayAudioStream(synth_stream);
// Main game loop // Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key while (!WindowShouldClose()) // Detect window close button or ESC key
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// TODO: Update your variables here if (detect_note_pressed(&current_note)) {
//get_note_sound(current_note);
SynthSound sound = get_note_sound(current_note);
//sound_buffer.sample_count = sound.sample_count;
//memcpy(sound_buffer.samples, sound.samples, sound.sample_count);
if (IsAudioStreamReady(synth_stream)) {
if (IsAudioStreamProcessed(synth_stream)) {
printf("Samples to play:%zu \n", sound.sample_count);
UpdateAudioStream(synth_stream, sound.samples, sound.sample_count);
}
}
//}
printf("Note played: %s\n", current_note.name);
}
//UpdateAudioStream(synth_stream, synth_sound.samples, synth_sound.sample_count);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@@ -406,7 +485,7 @@ int main(int argc, char **argv) {
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
} }
char* input = "A4-4 A4-4 A4-4 A4-4 A4-2 A4-4 A4-4 A4-4 A4-4 A4-4 A4-2 D5-4 D5-4 D5-4 D5-4 D5-4 D5-4 D5-2 C5-4 C5-4 C5-4 C5-4 C5-4 C5-4 C5-2 G4-2 "; char* input = "A4-4 A4-4 A4-4 A4-4 A4-2 A4-4 A4-4 A4-4 A4-4 A4-4 A4-2 D5-4 D5-4 D5-4 D5-4 D5-4 D5-4 D5-2 C5-4 C5-4 C5-4 C5-4 C5-4 C5-4 C5-2 G4-2 ";
char* buf = malloc(strlen(input) + 1); char* buf = malloc(strlen(input) + 1);
strcpy(buf, input); strcpy(buf, input);
@@ -428,6 +507,9 @@ int main(int argc, char **argv) {
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
StopAudioStream(synth_stream);
UnloadAudioStream(synth_stream);
CloseAudioDevice();
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------