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__
|
||||
#define __AMUSE_AUDIOGROUPPOOL_HPP__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
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
|
||||
{
|
||||
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:
|
||||
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 setDoppler(float doppler);
|
||||
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;
|
||||
}
|
||||
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:
|
||||
{
|
||||
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:
|
||||
{
|
||||
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::Envelope:
|
||||
case Op::StartSample:
|
||||
|
|
Loading…
Reference in New Issue