summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2024-10-09 03:12:15 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2024-10-09 03:12:15 +0200
commitcf2cfcd8a96921dbe812647045dff71ab63989cd (patch)
treeab097af301e539254b42dd5a4c1faf42a321e6df
parentc05e271a0507231eaf131930b5b9711ef85ae4a8 (diff)
downloadttdaw-cf2cfcd8a96921dbe812647045dff71ab63989cd.tar.gz
Added synth thread that plays a simple note
-rw-r--r--Makefile4
-rw-r--r--main.c13
-rw-r--r--synth.c67
-rw-r--r--synth.h11
4 files changed, 92 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 98a41d3..8681948 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
CC := cc
-CFLAGS := -Wall -Wextra -Wshadow -Wunused -Wswitch-enum -Wpedantic -Wundef
+CFLAGS := -Wall -Wextra -Wshadow -Wunused -Wswitch-enum -Wpedantic -ggdb
LDFLAGS := -lm -ldl -lpthread -lasound
-FILES := main.c midi.c minisdl_audio.c
+FILES := main.c midi.c synth.c minisdl_audio.c
PROG := ttdaw
$(PROG): main.c
diff --git a/main.c b/main.c
index 3a45592..5a1916e 100644
--- a/main.c
+++ b/main.c
@@ -6,6 +6,7 @@
#include "version.h"
#include "midi.h"
+#include "synth.h"
void help(const char *argv0) {
printf("Usage: %s [options]\n"
@@ -69,7 +70,16 @@ int main(int argc, char *argv[]) {
fprintf(stdout, "> Device port: %s\n", port_name);
fprintf(stdout, "> Soundfont: %s\n", soundfont_file);
- // Create and start MIDI thread.
+ // Create synth thread.
+ pthread_t synth_thread;
+ SynthArgs synth_args = { soundfont_file };
+
+ if (pthread_create(&synth_thread, NULL, synth, (void*)&synth_args) != 0) {
+ fprintf(stderr, "Error creating synth thread\n");
+ return 1;
+ }
+
+ // Create MIDI thread.
pthread_t midi_thread;
MidiArgs midi_args = { port_name };
@@ -79,6 +89,7 @@ int main(int argc, char *argv[]) {
}
pthread_join(midi_thread, NULL);
+ pthread_join(synth_thread, NULL);
fprintf(stdout, "Exiting...\n");
return 0;
diff --git a/synth.c b/synth.c
new file mode 100644
index 0000000..d391056
--- /dev/null
+++ b/synth.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#include "synth.h"
+#include "minisdl_audio.h"
+
+#define TSF_IMPLEMENTATION
+#include "tsf.h"
+
+static tsf* g_TinySoundFont;
+static SDL_mutex* g_Mutex;
+
+// Render the audio samples in float format.
+static void AudioCallback(void* data, Uint8 *stream, int len) {
+ int SampleCount = (len / (2 * sizeof(float))); // 2 output channels.
+ SDL_LockMutex(g_Mutex); // Get exclusive lock.
+ tsf_render_float(g_TinySoundFont, (float*)stream, SampleCount, 0);
+ SDL_UnlockMutex(g_Mutex);
+}
+
+void *synth(void *arg) {
+ SynthArgs* args = (SynthArgs*)arg;
+
+ SDL_AudioSpec OutputAudioSpec;
+ OutputAudioSpec.freq = 44100;
+ OutputAudioSpec.format = AUDIO_F32;
+ OutputAudioSpec.channels = 2;
+ OutputAudioSpec.samples = 4096;
+ OutputAudioSpec.callback = AudioCallback;
+
+ // Initialize the audio system.
+ if (SDL_AudioInit(TSF_NULL) < 0) {
+ fprintf(stderr, "Could not initialize audio hardware or driver\n");
+ exit(1);
+ }
+
+ // Load the SoundFont from a file.
+ g_TinySoundFont = tsf_load_filename(args->soundfont_file);
+ if (!g_TinySoundFont) {
+ fprintf(stderr, "Could not load SoundFont\n");
+ exit(1);
+ }
+
+ // Set the SoundFont rendering output mode.
+ tsf_set_output(g_TinySoundFont, TSF_STEREO_INTERLEAVED, OutputAudioSpec.freq, 0);
+
+ // Create the mutex.
+ g_Mutex = SDL_CreateMutex();
+
+ // Request the desired audio output format.
+ if (SDL_OpenAudio(&OutputAudioSpec, TSF_NULL) < 0) {
+ fprintf(stderr, "Could not open the audio hardware or the desired audio output format\n");
+ exit(1);
+ }
+
+ SDL_PauseAudio(0);
+
+ while (1) {
+ sleep(1);
+
+ SDL_LockMutex(g_Mutex);
+ tsf_note_off(g_TinySoundFont, 1, 50);
+ tsf_note_on(g_TinySoundFont, 1, 50, 1.0f);
+ SDL_UnlockMutex(g_Mutex);
+ }
+}
+
diff --git a/synth.h b/synth.h
new file mode 100644
index 0000000..1976745
--- /dev/null
+++ b/synth.h
@@ -0,0 +1,11 @@
+#ifndef SYNTH_H_
+#define SYNTH_H_
+
+typedef struct {
+ char *soundfont_file;
+} SynthArgs;
+
+void *synth(void *arg);
+
+#endif // SYNTH_H_
+