Added synth thread that plays a simple note

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2024-10-09 03:12:15 +0200
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2024-10-09 03:12:15 +0200
Commit cf2cfcd8a96921dbe812647045dff71ab63989cd (patch)
-rw-r--r-- Makefile 4
-rw-r--r-- main.c 13
-rw-r--r-- synth.c 67
-rw-r--r-- synth.h 11
4 files changed, 92 insertions, 3 deletions
diff --git a/Makefile b/Makefile
1
CC      := cc
1
CC      := cc
2
CFLAGS  := -Wall -Wextra -Wshadow -Wunused -Wswitch-enum -Wpedantic -Wundef
2
CFLAGS  := -Wall -Wextra -Wshadow -Wunused -Wswitch-enum -Wpedantic -ggdb
3
LDFLAGS := -lm -ldl -lpthread -lasound
3
LDFLAGS := -lm -ldl -lpthread -lasound
4
FILES   := main.c midi.c minisdl_audio.c
4
FILES   := main.c midi.c synth.c minisdl_audio.c
5
PROG    := ttdaw
5
PROG    := ttdaw
6
  
6
  
7
$(PROG): main.c
7
$(PROG): main.c
...
diff --git a/main.c b/main.c
...
6
  
6
  
7
#include "version.h"
7
#include "version.h"
8
#include "midi.h"
8
#include "midi.h"
  
9
#include "synth.h"
9
  
10
  
10
void help(const char *argv0) {
11
void help(const char *argv0) {
11
	printf("Usage: %s [options]\n"
12
	printf("Usage: %s [options]\n"
...
69
	fprintf(stdout, "> Device port:   %s\n", port_name);
70
	fprintf(stdout, "> Device port:   %s\n", port_name);
70
	fprintf(stdout, "> Soundfont:     %s\n", soundfont_file);
71
	fprintf(stdout, "> Soundfont:     %s\n", soundfont_file);
71
  
72
  
72
	// Create and start MIDI thread.
73
	// Create synth thread.
  
74
	pthread_t synth_thread;
  
75
	SynthArgs synth_args = { soundfont_file };
  
76
  
  
77
	if (pthread_create(&synth_thread, NULL, synth, (void*)&synth_args) != 0) {
  
78
		fprintf(stderr, "Error creating synth thread\n");
  
79
		return 1;
  
80
	}
  
81
  
  
82
	// Create MIDI thread.
73
	pthread_t midi_thread;
83
	pthread_t midi_thread;
74
	MidiArgs midi_args = { port_name };
84
	MidiArgs midi_args = { port_name };
75
  
85
  
...
79
	}
89
	}
80
  
90
  
81
	pthread_join(midi_thread, NULL);
91
	pthread_join(midi_thread, NULL);
  
92
	pthread_join(synth_thread, NULL);
82
  
93
  
83
	fprintf(stdout, "Exiting...\n");
94
	fprintf(stdout, "Exiting...\n");
84
	return 0;
95
	return 0;
...
diff --git a/synth.c b/synth.c
  
1
#include <stdio.h>
  
2
#include <unistd.h>
  
3
  
  
4
#include "synth.h"
  
5
#include "minisdl_audio.h"
  
6
  
  
7
#define TSF_IMPLEMENTATION
  
8
#include "tsf.h"
  
9
  
  
10
static tsf* g_TinySoundFont;
  
11
static SDL_mutex* g_Mutex;
  
12
  
  
13
// Render the audio samples in float format.
  
14
static void AudioCallback(void* data, Uint8 *stream, int len) {
  
15
	int SampleCount = (len / (2 * sizeof(float))); // 2 output channels.
  
16
	SDL_LockMutex(g_Mutex); // Get exclusive lock.
  
17
	tsf_render_float(g_TinySoundFont, (float*)stream, SampleCount, 0);
  
18
	SDL_UnlockMutex(g_Mutex);
  
19
}
  
20
  
  
21
void *synth(void *arg) {
  
22
	SynthArgs* args = (SynthArgs*)arg;
  
23
  
  
24
	SDL_AudioSpec OutputAudioSpec;
  
25
	OutputAudioSpec.freq = 44100;
  
26
	OutputAudioSpec.format = AUDIO_F32;
  
27
	OutputAudioSpec.channels = 2;
  
28
	OutputAudioSpec.samples = 4096;
  
29
	OutputAudioSpec.callback = AudioCallback;
  
30
  
  
31
	// Initialize the audio system.
  
32
	if (SDL_AudioInit(TSF_NULL) < 0) {
  
33
		fprintf(stderr, "Could not initialize audio hardware or driver\n");
  
34
		exit(1);
  
35
	}
  
36
  
  
37
	// Load the SoundFont from a file.
  
38
	g_TinySoundFont = tsf_load_filename(args->soundfont_file);
  
39
	if (!g_TinySoundFont) {
  
40
		fprintf(stderr, "Could not load SoundFont\n");
  
41
		exit(1);
  
42
	}
  
43
  
  
44
	// Set the SoundFont rendering output mode.
  
45
	tsf_set_output(g_TinySoundFont, TSF_STEREO_INTERLEAVED, OutputAudioSpec.freq, 0);
  
46
  
  
47
	// Create the mutex.
  
48
	g_Mutex = SDL_CreateMutex();
  
49
  
  
50
	// Request the desired audio output format.
  
51
	if (SDL_OpenAudio(&OutputAudioSpec, TSF_NULL) < 0) {
  
52
		fprintf(stderr, "Could not open the audio hardware or the desired audio output format\n");
  
53
		exit(1);
  
54
	}
  
55
  
  
56
	SDL_PauseAudio(0);
  
57
  
  
58
	while (1) {
  
59
		sleep(1);
  
60
  
  
61
		SDL_LockMutex(g_Mutex);
  
62
		tsf_note_off(g_TinySoundFont, 1, 50);
  
63
		tsf_note_on(g_TinySoundFont, 1, 50, 1.0f);
  
64
		SDL_UnlockMutex(g_Mutex);
  
65
	}
  
66
}
  
67
  
diff --git a/synth.h b/synth.h
  
1
#ifndef SYNTH_H_
  
2
#define SYNTH_H_
  
3
  
  
4
typedef struct {
  
5
	char *soundfont_file;
  
6
} SynthArgs;
  
7
  
  
8
void *synth(void *arg);
  
9
  
  
10
#endif //  SYNTH_H_
  
11