summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2024-10-09 17:59:41 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2024-10-09 17:59:41 +0200
commitbfc79cef2cb743fedba3e93fd005d25b0a4923dc (patch)
treeba322aea6b9ce203b9daf9b4b7b9280455027454
parentcf2cfcd8a96921dbe812647045dff71ab63989cd (diff)
downloadttdaw-bfc79cef2cb743fedba3e93fd005d25b0a4923dc.tar.gz
Added mutex and proper audio playback
-rw-r--r--Makefile2
-rw-r--r--main.c7
-rw-r--r--midi.c16
-rw-r--r--midi.h4
-rw-r--r--mutex.c19
-rw-r--r--mutex.h24
-rw-r--r--soundfonts/general-808.sf2bin0 -> 71680 bytes
-rw-r--r--synth.c31
-rw-r--r--synth.h4
9 files changed, 96 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 8681948..fca5cb9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
CC := cc
CFLAGS := -Wall -Wextra -Wshadow -Wunused -Wswitch-enum -Wpedantic -ggdb
LDFLAGS := -lm -ldl -lpthread -lasound
-FILES := main.c midi.c synth.c minisdl_audio.c
+FILES := main.c midi.c synth.c mutex.c minisdl_audio.c
PROG := ttdaw
$(PROG): main.c
diff --git a/main.c b/main.c
index 5a1916e..4eb4cf7 100644
--- a/main.c
+++ b/main.c
@@ -7,6 +7,7 @@
#include "version.h"
#include "midi.h"
#include "synth.h"
+#include "mutex.h"
void help(const char *argv0) {
printf("Usage: %s [options]\n"
@@ -70,6 +71,9 @@ int main(int argc, char *argv[]) {
fprintf(stdout, "> Device port: %s\n", port_name);
fprintf(stdout, "> Soundfont: %s\n", soundfont_file);
+ // Create mutex.
+ initialize_mutex();
+
// Create synth thread.
pthread_t synth_thread;
SynthArgs synth_args = { soundfont_file };
@@ -91,6 +95,9 @@ int main(int argc, char *argv[]) {
pthread_join(midi_thread, NULL);
pthread_join(synth_thread, NULL);
+ // Destroy mutex.
+ destroy_mutex();
+
fprintf(stdout, "Exiting...\n");
return 0;
}
diff --git a/midi.c b/midi.c
index 3d21f79..f389826 100644
--- a/midi.c
+++ b/midi.c
@@ -5,6 +5,7 @@
#include <alsa/asoundlib.h>
#include "midi.h"
+#include "mutex.h"
static snd_seq_t *seq_handle;
static snd_seq_addr_t *ports;
@@ -81,8 +82,12 @@ void *midi(void *arg) {
}
if (ev) {
+ pthread_mutex_lock(&mutex);
switch (ev->type) {
case SND_SEQ_EVENT_NOTEON:
+ shared_data.note = ev->data.note.note;
+ shared_data.state = 1;
+ shared_data.velocity = ev->data.note.velocity;
printf("%3d:%-3dNote on %2d, note %d, velocity: %3d\n",
ev->source.client, ev->source.port,
ev->data.note.channel,
@@ -91,14 +96,23 @@ void *midi(void *arg) {
break;
case SND_SEQ_EVENT_NOTEOFF:
+ shared_data.note = ev->data.note.note;
+ shared_data.state = 0;
+ shared_data.velocity = 0;
printf("%3d:%-3dNote off\t%2d, note %d\n",
ev->source.client, ev->source.port,
ev->data.note.channel,
ev->data.note.note);
break;
+ default:
+ break;
+ }
+ shared_data.action = 1;
+ shared_data.preset = 3;
- }
+ pthread_cond_signal(&cond_synth);
+ pthread_mutex_unlock(&mutex);
}
}
diff --git a/midi.h b/midi.h
index 81b105b..ddbaef8 100644
--- a/midi.h
+++ b/midi.h
@@ -1,8 +1,8 @@
-#include <alsa/asoundlib.h>
-
#ifndef MIDI_H_
#define MIDI_H_
+#include <alsa/asoundlib.h>
+
#define CLIENT_NAME "ttdaw"
#define MAX_MIDI_PORTS 1
diff --git a/mutex.c b/mutex.c
new file mode 100644
index 0000000..007928d
--- /dev/null
+++ b/mutex.c
@@ -0,0 +1,19 @@
+#include <pthread.h>
+#include "mutex.h"
+
+SharedData shared_data;
+
+pthread_mutex_t mutex;
+pthread_cond_t cond_midi;
+pthread_cond_t cond_synth;
+
+void initialize_mutex() {
+ pthread_mutex_init(&mutex, NULL);
+ pthread_cond_init(&cond_synth, NULL);
+}
+
+void destroy_mutex() {
+ pthread_mutex_destroy(&mutex);
+ pthread_cond_destroy(&cond_synth);
+}
+
diff --git a/mutex.h b/mutex.h
new file mode 100644
index 0000000..2f3c653
--- /dev/null
+++ b/mutex.h
@@ -0,0 +1,24 @@
+#ifndef MUTEX_H
+#define MUTEX_H
+
+#include <pthread.h>
+
+typedef struct {
+ int note;
+ int state;
+ int velocity;
+ int preset;
+ int action;
+} SharedData;
+
+extern SharedData shared_data;
+
+extern pthread_mutex_t mutex;
+extern pthread_cond_t cond_midi;
+extern pthread_cond_t cond_synth;
+
+void initialize_mutex();
+void destroy_mutex();
+
+#endif // MUTEX_H
+
diff --git a/soundfonts/general-808.sf2 b/soundfonts/general-808.sf2
new file mode 100644
index 0000000..3e128d8
--- /dev/null
+++ b/soundfonts/general-808.sf2
Binary files differ
diff --git a/synth.c b/synth.c
index d391056..05c3664 100644
--- a/synth.c
+++ b/synth.c
@@ -2,6 +2,7 @@
#include <unistd.h>
#include "synth.h"
+#include "mutex.h"
#include "minisdl_audio.h"
#define TSF_IMPLEMENTATION
@@ -12,7 +13,7 @@ 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.
+ int SampleCount = (len / (AUDIO_CHANNELS * 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);
@@ -22,10 +23,10 @@ void *synth(void *arg) {
SynthArgs* args = (SynthArgs*)arg;
SDL_AudioSpec OutputAudioSpec;
- OutputAudioSpec.freq = 44100;
+ OutputAudioSpec.freq = AUDIO_FREQ;
OutputAudioSpec.format = AUDIO_F32;
- OutputAudioSpec.channels = 2;
- OutputAudioSpec.samples = 4096;
+ OutputAudioSpec.channels = AUDIO_CHANNELS;
+ OutputAudioSpec.samples = AUDIO_SAMPLES;
OutputAudioSpec.callback = AudioCallback;
// Initialize the audio system.
@@ -56,12 +57,28 @@ void *synth(void *arg) {
SDL_PauseAudio(0);
while (1) {
- sleep(1);
+ pthread_mutex_lock(&mutex);
+ while (shared_data.action == 0) {
+ pthread_cond_wait(&cond_synth, &mutex);
+ }
SDL_LockMutex(g_Mutex);
- tsf_note_off(g_TinySoundFont, 1, 50);
- tsf_note_on(g_TinySoundFont, 1, 50, 1.0f);
+
+ if (shared_data.state == 0) {
+ tsf_note_off(g_TinySoundFont, shared_data.preset, shared_data.note);
+ } else {
+ float normalized_velocity = (float)shared_data.velocity / 127.0f;
+ tsf_note_on(g_TinySoundFont, shared_data.preset, shared_data.note, normalized_velocity);
+ }
+
SDL_UnlockMutex(g_Mutex);
+
+ printf("Consumed: note=%d, state=%d velocity:%d\n", shared_data.note, shared_data.state, shared_data.velocity);
+
+ // Reset state to indicate data has been consumed.
+ shared_data.action = 0;
+
+ pthread_mutex_unlock(&mutex);
}
}
diff --git a/synth.h b/synth.h
index 1976745..90fd410 100644
--- a/synth.h
+++ b/synth.h
@@ -1,6 +1,10 @@
#ifndef SYNTH_H_
#define SYNTH_H_
+#define AUDIO_FREQ 44100
+#define AUDIO_SAMPLES 64
+#define AUDIO_CHANNELS 2
+
typedef struct {
char *soundfont_file;
} SynthArgs;