summaryrefslogtreecommitdiff
path: root/src/factories/fzerox/SoundFontFactory.h
blob: 1669cbe4ef9ad9dccb9bc7cad24e5d61960b8f3a (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
115
116
117
118
#pragma once

#include <factories/BaseFactory.h>
#include <unordered_set>

namespace FZX {

typedef struct TunedSample {
    std::string sampleRef;
    float tuning;
} TunedSample;

typedef struct Drum {
    uint8_t adsrDecayIndex;
    uint8_t pan;
    uint8_t isRelocated;
    TunedSample tunedSample;
    std::string envelopeRef;
} Drum;

typedef struct SoundEffect {
    TunedSample tunedSample;
} SoundEffect;

typedef struct Instrument {
    uint8_t isRelocated;
    uint8_t normalRangeLo;
    uint8_t normalRangeHi;
    uint8_t adsrDecayIndex;
    std::string envelopeRef;
    TunedSample lowPitchTunedSample;
    TunedSample normalPitchTunedSample;
    TunedSample highPitchTunedSample;
} Instrument;

typedef struct EnvelopePoint {
    int16_t delay;
    int16_t arg;
} EnvelopePoint;

typedef struct Sample {
    uint32_t codec;
    uint32_t medium;
    uint32_t unk_bit26;
    uint32_t isRelocated;
    uint32_t size;
    uint32_t rawSampleOffset;
    std::string loopRef;
    std::string bookRef;
} Sample;

typedef struct AdpcmBook {
    int32_t order;
    int32_t numPredictors;
    std::vector<int16_t> book;
} AdpcmBook;

typedef struct AdpcmLoop {
    uint32_t start;
    uint32_t end;
    uint32_t count;
    std::vector<int16_t> predictorState;
} AdpcmLoop;

enum class DataType {
    Drum,
    Sfx,
    Instrument,
    Envelope,
    Sample,
    Book,
    Loop,
    DrumOffsets,
};

typedef std::variant<Drum, std::vector<SoundEffect>, Instrument, std::vector<EnvelopePoint>, Sample, AdpcmBook, AdpcmLoop, std::vector<std::string>> SoundFontType;

typedef struct SoundFontEntry {
    std::string name;
    DataType type;
    SoundFontType data;
} SoundFontEntry;

class SoundFontData : public IParsedData {
public:

    std::vector<SoundFontEntry> mEntries;
    bool mSupportSfx;

    SoundFontData(std::vector<SoundFontEntry> entries, bool supportSfx) : mEntries(std::move(entries)), mSupportSfx(supportSfx) {}
};

class SoundFontHeaderExporter : public BaseExporter {
    ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class SoundFontBinaryExporter : public BaseExporter {
    ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class SoundFontCodeExporter : public BaseExporter {
    ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class SoundFontFactory : public BaseFactory {
public:
    std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
    inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
        return {
            REGISTER(Code, SoundFontCodeExporter)
            REGISTER(Header, SoundFontHeaderExporter)
            REGISTER(Binary, SoundFontBinaryExporter)
        };
    }
private:
    std::string RegisterSoundFontData(std::string symbol, FZX::DataType dataType, uint32_t offset, std::map<uint32_t, std::pair<FZX::DataType, std::string>>& dataMap, std::unordered_map<FZX::DataType, uint32_t>& dataCountMap);
};
}