summaryrefslogtreecommitdiff
path: root/src/port/audio/HMAS.h
blob: c8ac4cd010c71922e24f994fb861cd4e2e780e09 (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
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
#pragma once

typedef int HMAS_AudioId;

enum HMAS_ChannelId {
    HMAS_MUSIC,
    HMAS_SFX,
    HMAS_ENV,
    HMAS_MAX_CHANNELS
};

enum HMAS_EffectType {
    HMAS_EFFECT_VOLUME,
    HMAS_EFFECT_PITCH,
    HMAS_EFFECT_PAUSE,
    HMAS_EFFECT_STOP
};

enum HMAS_EffectTransition {
    HMAS_LINEAR,
    HMAS_INSTANT
};

#ifdef __cplusplus

#include <string>
#include <vector>
#include <cstdint>
#include <unordered_map>
#include "audio/miniaudio.h"

struct HMAS_Loop {
    int64_t start;
    int64_t end;
};

struct HMAS_Info {
    HMAS_Loop loop = { -1, -1 };
    std::string name;
    std::string author;
    std::string date;
};

struct HMAS_Sample {
    ma_sound sound;
    ma_decoder decoder;

    HMAS_Info info;
};

struct HMAS_Effect {
    HMAS_EffectType type;
    HMAS_EffectTransition transition;
    uint32_t numFrames;
    float target;
};

struct HMAS_ChannelInfo {
    ma_sound* sound;

    ma_uint64 cursor;
    float pitch;
    float volume;

    std::vector<HMAS_Effect> effects;
};

class HMAS {
public:
    HMAS();
    ~HMAS();

    void RegisterSound(HMAS_AudioId id, const std::string& filePath, HMAS_Info info = {});
    void RegisterSound(HMAS_AudioId id, uint8_t* data, uint32_t size, HMAS_Info info = {});

    void Play(HMAS_ChannelId channel, HMAS_AudioId id, bool loop = false);
    void Stop(HMAS_ChannelId channel);
    bool IsPlaying(HMAS_ChannelId channel);

    void SetPitch(HMAS_ChannelId channel, float pitch);
    void SetVolume(HMAS_ChannelId channel, float volume);
    void SetPause(HMAS_ChannelId channel, bool pause);
    void AddEffect(HMAS_ChannelId channel, HMAS_EffectType type, HMAS_EffectTransition transition, uint32_t frames, float target);

    bool IsIDRegistered(HMAS_AudioId id);

    void ProcessEffects();
    void CreateBuffer(uint8_t* samples, uint32_t num_samples);

    float Lerp(float a, float b, float t) {
        return a + (b - a) * t;
    }

private:
    ma_engine gAudioEngine;
    HMAS_ChannelInfo gChannelSound[HMAS_MAX_CHANNELS] = { 0 };
    std::unordered_map<HMAS_AudioId, HMAS_Sample> gRegistry;
};

extern "C" {
#endif

void HMAS_Play(enum HMAS_ChannelId channel, HMAS_AudioId id, bool loop);
void HMAS_Stop(enum HMAS_ChannelId channel);
bool HMAS_IsPlaying(enum HMAS_ChannelId channel);
void HMAS_SetPitch(enum HMAS_ChannelId channel, float pitch);
void HMAS_SetVolume(enum HMAS_ChannelId channel, float volume);
void HMAS_SetPause(enum HMAS_ChannelId channel, bool pause);
void HMAS_AddEffect(enum HMAS_ChannelId channel, enum HMAS_EffectType type, enum HMAS_EffectTransition transition, uint32_t frames, float target);
bool HMAS_IsIDRegistered(HMAS_AudioId id);

#ifdef __cplusplus
}
#endif