mirror of https://github.com/AxioDL/amuse.git
Add AudioGroup pool reading
This commit is contained in:
parent
3510c0a2e8
commit
fa66632b7c
|
@ -1,13 +1,70 @@
|
||||||
#ifndef __AMUSE_AUDIOGROUPPOOL_HPP__
|
#ifndef __AMUSE_AUDIOGROUPPOOL_HPP__
|
||||||
#define __AMUSE_AUDIOGROUPPOOL_HPP__
|
#define __AMUSE_AUDIOGROUPPOOL_HPP__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** Defines phase-based volume curve for macro volume control */
|
||||||
|
struct ADSR
|
||||||
|
{
|
||||||
|
uint8_t attackFine; /* 0-255ms */
|
||||||
|
uint8_t attackCoarse; /* 0-65280ms */
|
||||||
|
uint8_t decayFine; /* 0-255ms */
|
||||||
|
uint8_t decayCoarse; /* 0-65280ms */
|
||||||
|
uint8_t sustainFine; /* multiply by 0.0244 for percentage */
|
||||||
|
uint8_t sustainCoarse; /* multiply by 6.25 for percentage */
|
||||||
|
uint8_t releaseFine; /* 0-255ms */
|
||||||
|
uint8_t releaseCoarse; /* 0-65280ms */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Curves for mapping velocity to volume and other functional mappings */
|
||||||
|
using Curves = uint8_t[128];
|
||||||
|
|
||||||
|
/** Maps individual MIDI keys to sound-entity as indexed in table
|
||||||
|
* (macro-voice, keymap, layer) */
|
||||||
|
struct Keymap
|
||||||
|
{
|
||||||
|
int16_t objectId;
|
||||||
|
int8_t transpose;
|
||||||
|
int8_t pan; /* -128 for surround-channel only */
|
||||||
|
int8_t prioOffset;
|
||||||
|
int8_t pad[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Maps ranges of MIDI keys to sound-entity (macro-voice, keymap, layer) */
|
||||||
|
struct LayerMapping
|
||||||
|
{
|
||||||
|
int16_t objectId;
|
||||||
|
int8_t keyLo;
|
||||||
|
int8_t keyHi;
|
||||||
|
int8_t transpose;
|
||||||
|
int8_t volume;
|
||||||
|
int8_t pan; /* -128 for surround-channel only */
|
||||||
|
int8_t prioOffset;
|
||||||
|
int8_t unk; /* usually 0x40 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Database of functional objects within Audio Group */
|
||||||
class AudioGroupPool
|
class AudioGroupPool
|
||||||
{
|
{
|
||||||
|
std::unordered_map<int, const unsigned char*> m_soundMacros;
|
||||||
|
std::unordered_map<int, const unsigned char*> m_tables;
|
||||||
|
std::unordered_map<int, const Keymap*> m_keymaps;
|
||||||
|
std::unordered_map<int, std::vector<const LayerMapping*>> m_layers;
|
||||||
public:
|
public:
|
||||||
AudioGroupPool(const unsigned char* data);
|
AudioGroupPool(const unsigned char* data);
|
||||||
|
const ADSR* tableAsAdsr(int id) const
|
||||||
|
{
|
||||||
|
auto search = m_tables.find(id);
|
||||||
|
if (search == m_tables.cend())
|
||||||
|
return nullptr;
|
||||||
|
return reinterpret_cast<const ADSR*>(search->second);
|
||||||
|
}
|
||||||
|
const Curves* tableAsCurves(int id) const {return reinterpret_cast<const Curves*>(tableAsAdsr(id));}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
void setPedal(bool pedal);
|
void setPedal(bool pedal);
|
||||||
void setDoppler(float doppler);
|
void setDoppler(float doppler);
|
||||||
void setReverbVol(float rvol);
|
void setReverbVol(float rvol);
|
||||||
|
void setAdsr(int adsrIdx, uint8_t type);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
#include "amuse/AudioGroupPool.hpp"
|
||||||
|
#include "amuse/Common.hpp"
|
||||||
|
|
||||||
|
namespace amuse
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
uint32_t soundMacrosOffset;
|
||||||
|
uint32_t tablesOffset;
|
||||||
|
uint32_t keymapsOffset;
|
||||||
|
uint32_t layersOffset;
|
||||||
|
void swapBig()
|
||||||
|
{
|
||||||
|
soundMacrosOffset = SBig(soundMacrosOffset);
|
||||||
|
tablesOffset = SBig(tablesOffset);
|
||||||
|
keymapsOffset = SBig(keymapsOffset);
|
||||||
|
layersOffset = SBig(layersOffset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AudioGroupPool::AudioGroupPool(const unsigned char* data)
|
||||||
|
{
|
||||||
|
Header head = *reinterpret_cast<const Header*>(data);
|
||||||
|
head.swapBig();
|
||||||
|
|
||||||
|
if (head.soundMacrosOffset)
|
||||||
|
{
|
||||||
|
const unsigned char* cur = data + head.soundMacrosOffset;
|
||||||
|
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
||||||
|
{
|
||||||
|
uint32_t size = SBig(*reinterpret_cast<const uint32_t*>(cur));
|
||||||
|
uint16_t id = SBig(*reinterpret_cast<const uint16_t*>(cur + 4));
|
||||||
|
m_soundMacros[id] = cur + 8;
|
||||||
|
cur += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head.tablesOffset)
|
||||||
|
{
|
||||||
|
const unsigned char* cur = data + head.tablesOffset;
|
||||||
|
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
||||||
|
{
|
||||||
|
uint32_t size = SBig(*reinterpret_cast<const uint32_t*>(cur));
|
||||||
|
uint16_t id = SBig(*reinterpret_cast<const uint16_t*>(cur + 4));
|
||||||
|
m_tables[id] = cur + 8;
|
||||||
|
cur += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head.keymapsOffset)
|
||||||
|
{
|
||||||
|
const unsigned char* cur = data + head.keymapsOffset;
|
||||||
|
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
||||||
|
{
|
||||||
|
uint32_t size = SBig(*reinterpret_cast<const uint32_t*>(cur));
|
||||||
|
uint16_t id = SBig(*reinterpret_cast<const uint16_t*>(cur + 4));
|
||||||
|
m_keymaps[id] = reinterpret_cast<const Keymap*>(cur + 8);
|
||||||
|
cur += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head.layersOffset)
|
||||||
|
{
|
||||||
|
const unsigned char* cur = data + head.layersOffset;
|
||||||
|
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
||||||
|
{
|
||||||
|
uint32_t size = SBig(*reinterpret_cast<const uint32_t*>(cur));
|
||||||
|
uint16_t id = SBig(*reinterpret_cast<const uint16_t*>(cur + 4));
|
||||||
|
std::vector<const LayerMapping*>& mappingsOut = m_layers[id];
|
||||||
|
|
||||||
|
uint32_t count = SBig(*reinterpret_cast<const uint32_t*>(cur+8));
|
||||||
|
mappingsOut.reserve(count);
|
||||||
|
const unsigned char* subcur = cur + 12;
|
||||||
|
for (int i=0 ; i<count ; ++i)
|
||||||
|
mappingsOut.push_back(reinterpret_cast<const LayerMapping*>(subcur + i * 12));
|
||||||
|
|
||||||
|
cur += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -285,8 +285,32 @@ bool SoundMacroState::advance(Voice& vox, float dt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Op::PianoPan:
|
case Op::PianoPan:
|
||||||
|
{
|
||||||
|
int8_t scale = cmd.m_data[0];
|
||||||
|
int8_t cenKey = cmd.m_data[1];
|
||||||
|
int8_t cenPan = cmd.m_data[2];
|
||||||
|
|
||||||
|
int32_t pan = int32_t(m_midiKey - cenKey) * scale / 127 + cenPan;
|
||||||
|
pan = std::max(-127, std::min(127, pan));
|
||||||
|
vox.setPanning(pan / 127.f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Op::SetAdsr:
|
case Op::SetAdsr:
|
||||||
|
{
|
||||||
|
int16_t tableId = *reinterpret_cast<int16_t*>(&cmd.m_data[0]);
|
||||||
|
uint8_t type = cmd.m_data[2];
|
||||||
|
vox.setAdsr(tableId, type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Op::ScaleVolume:
|
case Op::ScaleVolume:
|
||||||
|
{
|
||||||
|
int8_t scale = cmd.m_data[0];
|
||||||
|
int8_t add = cmd.m_data[1];
|
||||||
|
int16_t curve = *reinterpret_cast<int16_t*>(&cmd.m_data[2]);
|
||||||
|
bool orgVel = cmd.m_data[4];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Op::Panning:
|
case Op::Panning:
|
||||||
case Op::Envelope:
|
case Op::Envelope:
|
||||||
case Op::StartSample:
|
case Op::StartSample:
|
||||||
|
|
Loading…
Reference in New Issue