summaryrefslogtreecommitdiff
path: root/src/mixer/mixer.h
blob: fec06eaa84ba1ec42b48d8e6e6a58d038f98d77a (plain)
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
#pragma once

#include <al/types.h>
#include <al/array.h>
#include <al/atomic.h>
#ifdef CAMU_MIXER_THREADED
#include <nnwt/thread.h>
#endif

#include "../codec/codec.h"

#ifdef CAMU_MIXER_THREADED
// Do we need a lock in order to synchronize the mixers paused state.
// Disabling this is a very specific optimization to allow the audio device to buffer
// data during start(). It requires pause(), resume(), and remove_buffer() to all
// come from the same thread.
//#define CAMU_MIXER_THREADED_START_STOP
#endif

enum {
    CAMU_MIXER_EMPTY = 0
};

struct camu_mixer {
    struct camu_audio *audio;
    f32 volume;
    struct camu_resampler_format fmt;
    atomic(bool) paused;
    u8 empty_after;
    array(struct camu_audio_buffer *) buffers;
#ifdef CAMU_MIXER_THREADED
    array(struct camu_audio_buffer *) add_queue;
    array(struct camu_audio_buffer *) rem_queue;
    atomic(bool) queued;
    struct nn_mutex mutex;
#endif
    void (*callback)(void *, u8);
    void *userdata;
};

bool camu_mixer_init(struct camu_mixer *mixer, struct camu_audio *audio);
void camu_mixer_pick_format(struct camu_mixer *mixer, struct camu_resampler_format *fmt);
void camu_mixer_set_volume(struct camu_mixer *mixer, f32 volume);
f32 camu_mixer_offset_volume(struct camu_mixer *mixer, f32 amount);
f64 camu_mixer_get_latency(struct camu_mixer *mixer);
void camu_mixer_add_buffer(struct camu_mixer *mixer, struct camu_audio_buffer *buf);
void camu_mixer_remove_buffer(struct camu_mixer *mixer, struct camu_audio_buffer *buf);
#ifdef CAMU_MIXER_THREADED
void camu_mixer_run_queue(struct camu_mixer *mixer);
void camu_mixer_clear(struct camu_mixer *mixer);
#endif
void camu_mixer_pause(struct camu_mixer *mixer);
void camu_mixer_resume(struct camu_mixer *mixer);
void camu_mixer_close(struct camu_mixer *mixer);