-
Notifications
You must be signed in to change notification settings - Fork 0
/
jumaudio.h
147 lines (123 loc) · 4.46 KB
/
jumaudio.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* Copyright (c) 2022 Hunter Whyte */
#ifndef JUMAUDIO_H_
#define JUMAUDIO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <pthread.h>
#include <semaphore.h>
#include <stdbool.h>
#include "miniaudio/miniaudio.h"
#include "pffft/pffft.h"
#define M_PI 3.14159265358979323846
// 1500 samples (~35ms)
#define MAX_DESYNC 1500
#define MAX_SOUND_FILES 32
#define SOUND_FLAGS (MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC)
// read only after setup
typedef struct audioInfo {
ma_uint32 sample_rate;
ma_uint32 bytes_per_frame;
ma_uint32 channels;
ma_format format;
ma_uint32 period;
} AudioInfo;
// read/write for init and audio stream callback, read only for everything else
// all accesses after intialization should acquire mutex
typedef struct audioControl {
sem_t mutex;
ma_int32 writer_pos;
ma_int32 reader_pos;
bool new_data_flag;
float music_volume;
float other_volume;
} AudioControl;
typedef struct audioBuffer {
// lock free, single producer, single consumer circular buffer
float* buf;
ma_int32 sz;
ma_int32 allocated_sz;
} AudioBuffer;
typedef enum {
AUDIO_MODE_NONE,
AUDIO_MODE_PLAYBACK,
AUDIO_MODE_CAPTURE,
} jum_AudioMode;
// absolute filepath along with its associated ma_audio sound
typedef struct sound_file {
char* filepath;
ma_sound sound;
} SoundFile;
// audio player/capturer setup
typedef struct jum_audio {
AudioBuffer buffer;
AudioControl control;
AudioInfo info;
float* conversion_buf;
ma_uint32 conversion_sz;
ma_int32 predecode_bufs;
ma_context context;
ma_resource_manager resource_manager;
ma_engine music_engine; // sounds played from this engine will have FFT performed
SoundFile song_file; // the single sound playing on the music engine
ma_engine other_engine; // sounds played from this engine will not contribute to FFT
SoundFile sound_files[MAX_SOUND_FILES];
ma_int32 num_sound_files;
ma_device playback_device;
bool playback_open;
ma_device capture_device;
bool capture_open;
jum_AudioMode mode;
ma_device_info* playback_device_info;
ma_device_info* capture_device_info;
ma_uint32 playback_device_count, capture_device_count;
} jum_AudioSetup;
// pffft data
typedef struct pffftinfo {
ma_int32 sz;
float* in;
float* out;
PFFFT_Setup* setup;
} PFFFTInfo;
typedef struct fft_tables {
float* freqs; // frequencies for each bin
float* weights; // weights applied for each frequency bin
float* hamming; // constants to multiple input by for hamming window
} FFTTables;
typedef struct jum_fft {
PFFFTInfo pffft; // pffft setup and inout buffers
ma_int32 num_bins; // number of output frequncy bins
float* raw; // raw fft output, num_bins size
float* averaged; // fft with averaging over time, num_bins size
float* result; // final fft with averaging and weighting, num_bins size
FFTTables luts; // lookup tables generated on init
float max; // max result ever output, keep track for normalizing output
ma_int32 pos; // last pos in audio buffer used for fft
float level; // average audio level of the audio buffer
} jum_FFTSetup;
jum_AudioSetup* jum_initAudio(ma_uint32 buffer_size, ma_uint32 predecode_bufs, ma_uint32 period);
void jum_deinitAudio(jum_AudioSetup* setup);
ma_int32 jum_openPlaybackDevice(jum_AudioSetup* setup, ma_int32 device_index);
ma_int32 jum_openCaptureDevice(jum_AudioSetup* setup, ma_int32 device_index);
void jum_printAudioInfo(AudioInfo info);
void jum_analyze(jum_FFTSetup* fft, jum_AudioSetup* audio, ma_uint32 msec);
jum_FFTSetup* jum_initFFT(const float freq_points[][2], ma_int32 freqs_sz,
const float weight_points[][2], ma_int32 weights_sz, ma_int32 fft_sz,
ma_int32 num_bins);
void jum_deinitFFT(jum_FFTSetup* setup);
void jum_setMusicVolume(jum_AudioSetup* setup, float volume);
void jum_setOtherVolume(jum_AudioSetup* setup, float volume);
ma_int32 jum_playSong(jum_AudioSetup* setup, const char* filepath);
float jum_getSongCursor(jum_AudioSetup* setup);
float jum_getSongLength(jum_AudioSetup* setup);
bool jum_isSongFinished(jum_AudioSetup* setup);
void jum_pauseSong(jum_AudioSetup* setup);
void jum_resumeSong(jum_AudioSetup* setup);
ma_int32 jum_loadSound(jum_AudioSetup* setup, const char* filepath);
ma_int32 jum_playSound(jum_AudioSetup* setup, ma_int32 handle, float repeat_delay);
void jum_clearSoundFiles(jum_AudioSetup* setup);
void jum_setFFTMode(jum_AudioSetup* setup, jum_AudioMode mode);
#ifdef __cplusplus
}
#endif
#endif // JUMAUDIO_H_