mirror of https://github.com/AxioDL/amuse.git
Initial working AudioUnit integration
This commit is contained in:
parent
f260019b89
commit
117d7046dd
|
@ -127,11 +127,12 @@ struct AudioGroupCollection
|
||||||
{
|
{
|
||||||
@public
|
@public
|
||||||
NSString* m_name;
|
NSString* m_name;
|
||||||
|
int m_id;
|
||||||
const amuse::SongGroupIndex* m_song;
|
const amuse::SongGroupIndex* m_song;
|
||||||
const amuse::SFXGroupIndex* m_sfx;
|
const amuse::SFXGroupIndex* m_sfx;
|
||||||
}
|
}
|
||||||
- (id)initWithName:(NSString*)name songGroup:(const amuse::SongGroupIndex*)group;
|
- (id)initWithName:(NSString*)name id:(int)gid songGroup:(const amuse::SongGroupIndex*)group;
|
||||||
- (id)initWithName:(NSString*)name sfxGroup:(const amuse::SFXGroupIndex*)group;
|
- (id)initWithName:(NSString*)name id:(int)gid sfxGroup:(const amuse::SFXGroupIndex*)group;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface AudioGroupFilePresenter : NSObject <NSFilePresenter, NSOutlineViewDataSource, NSOutlineViewDelegate>
|
@interface AudioGroupFilePresenter : NSObject <NSFilePresenter, NSOutlineViewDataSource, NSOutlineViewDelegate>
|
||||||
|
@ -139,7 +140,6 @@ struct AudioGroupCollection
|
||||||
@public
|
@public
|
||||||
id<AudioGroupClient> m_audioGroupClient;
|
id<AudioGroupClient> m_audioGroupClient;
|
||||||
NSURL* m_groupURL;
|
NSURL* m_groupURL;
|
||||||
NSOperationQueue* m_dataQueue;
|
|
||||||
std::map<std::string, std::unique_ptr<AudioGroupCollection>> m_audioGroupCollections;
|
std::map<std::string, std::unique_ptr<AudioGroupCollection>> m_audioGroupCollections;
|
||||||
std::vector<std::map<std::string, std::unique_ptr<AudioGroupCollection>>::iterator> m_filterAudioGroupCollections;
|
std::vector<std::map<std::string, std::unique_ptr<AudioGroupCollection>>::iterator> m_filterAudioGroupCollections;
|
||||||
NSOutlineView* m_lastOutlineView;
|
NSOutlineView* m_lastOutlineView;
|
||||||
|
|
|
@ -53,18 +53,20 @@ static std::string StrToLower(const std::string& str)
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AudioGroupToken
|
@implementation AudioGroupToken
|
||||||
- (id)initWithName:(NSString*)name songGroup:(const amuse::SongGroupIndex*)group
|
- (id)initWithName:(NSString*)name id:(int)gid songGroup:(const amuse::SongGroupIndex*)group
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_song = group;
|
m_song = group;
|
||||||
|
m_id = gid;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
- (id)initWithName:(NSString*)name sfxGroup:(const amuse::SFXGroupIndex*)group
|
- (id)initWithName:(NSString*)name id:(int)gid sfxGroup:(const amuse::SFXGroupIndex*)group
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_sfx = group;
|
m_sfx = group;
|
||||||
|
m_id = gid;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -78,7 +80,7 @@ static std::string StrToLower(const std::string& str)
|
||||||
|
|
||||||
- (NSOperationQueue*)presentedItemOperationQueue
|
- (NSOperationQueue*)presentedItemOperationQueue
|
||||||
{
|
{
|
||||||
return m_dataQueue;
|
return [NSOperationQueue mainQueue];
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioGroupCollection::AudioGroupCollection(NSURL* url)
|
AudioGroupCollection::AudioGroupCollection(NSURL* url)
|
||||||
|
@ -305,7 +307,8 @@ bool AudioGroupDataCollection::_indexData(AudioGroupFilePresenter* presenter)
|
||||||
for (const auto& pair : sortGroups)
|
for (const auto& pair : sortGroups)
|
||||||
{
|
{
|
||||||
NSString* name = [NSString stringWithFormat:@"%d", pair.first];
|
NSString* name = [NSString stringWithFormat:@"%d", pair.first];
|
||||||
m_groupTokens.push_back([[AudioGroupToken alloc] initWithName:name songGroup:pair.second]);
|
m_groupTokens.push_back([[AudioGroupToken alloc] initWithName:name id:pair.first
|
||||||
|
songGroup:pair.second]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -316,7 +319,8 @@ bool AudioGroupDataCollection::_indexData(AudioGroupFilePresenter* presenter)
|
||||||
for (const auto& pair : sortGroups)
|
for (const auto& pair : sortGroups)
|
||||||
{
|
{
|
||||||
NSString* name = [NSString stringWithFormat:@"%d", pair.first];
|
NSString* name = [NSString stringWithFormat:@"%d", pair.first];
|
||||||
m_groupTokens.push_back([[AudioGroupToken alloc] initWithName:name sfxGroup:pair.second]);
|
m_groupTokens.push_back([[AudioGroupToken alloc] initWithName:name id:pair.first
|
||||||
|
sfxGroup:pair.second]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -495,12 +499,10 @@ bool AudioGroupDataCollection::loadMeta(AudioGroupFilePresenter* presenter)
|
||||||
return ret.operator bool();
|
return ret.operator bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)presentedSubitemDidAppearAtURL:(NSURL*)url
|
- (void)presentedSubitemDidChangeAtURL:(NSURL *)url
|
||||||
{
|
{
|
||||||
if ([url.lastPathComponent isEqualToString:@"proj"] ||
|
size_t relComps = url.pathComponents.count - m_groupURL.pathComponents.count;
|
||||||
[url.lastPathComponent isEqualToString:@"pool"] ||
|
if (relComps <= 1)
|
||||||
[url.lastPathComponent isEqualToString:@"sdir"] ||
|
|
||||||
[url.lastPathComponent isEqualToString:@"samp"])
|
|
||||||
[self update];
|
[self update];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +852,6 @@ bool AudioGroupDataCollection::loadMeta(AudioGroupFilePresenter* presenter)
|
||||||
m_groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.io.github.axiodl.Amuse.AudioGroups"];
|
m_groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.io.github.axiodl.Amuse.AudioGroups"];
|
||||||
if (!m_groupURL)
|
if (!m_groupURL)
|
||||||
return nil;
|
return nil;
|
||||||
m_dataQueue = [NSOperationQueue new];
|
|
||||||
[NSFileCoordinator addFilePresenter:self];
|
[NSFileCoordinator addFilePresenter:self];
|
||||||
[self update];
|
[self update];
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -49,6 +49,7 @@ void RegisterAudioUnit();
|
||||||
- (nullable id)initWithComponentDescription:(AudioComponentDescription)componentDescription
|
- (nullable id)initWithComponentDescription:(AudioComponentDescription)componentDescription
|
||||||
error:(NSError * __nullable * __nonnull)outError
|
error:(NSError * __nullable * __nonnull)outError
|
||||||
viewController:(AudioUnitViewController* __nonnull)vc;
|
viewController:(AudioUnitViewController* __nonnull)vc;
|
||||||
|
- (void)requestAudioGroup:(AudioGroupToken*)group;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,8 @@ static logvisor::Module Log("amuse::AudioUnitBackend");
|
||||||
|
|
||||||
struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||||
{
|
{
|
||||||
|
AudioGroupToken* m_reqGroup = nullptr;
|
||||||
|
AudioGroupToken* m_curGroup = nullptr;
|
||||||
std::vector<float> m_interleavedBuf;
|
std::vector<float> m_interleavedBuf;
|
||||||
std::vector<std::unique_ptr<float[]>> m_renderBufs;
|
std::vector<std::unique_ptr<float[]>> m_renderBufs;
|
||||||
size_t m_renderFrames = 0;
|
size_t m_renderFrames = 0;
|
||||||
|
@ -137,6 +139,8 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double getCurrentSampleRate() const {return m_mixInfo.m_sampleRate;}
|
||||||
};
|
};
|
||||||
|
|
||||||
@implementation AmuseAudioUnit
|
@implementation AmuseAudioUnit
|
||||||
|
@ -165,7 +169,9 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||||
//m_outBus.supportedChannelCounts = @[@1,@2];
|
//m_outBus.supportedChannelCounts = @[@1,@2];
|
||||||
m_outBus.maximumChannelCount = 2;
|
m_outBus.maximumChannelCount = 2;
|
||||||
|
|
||||||
m_outs = [[AUAudioUnitBusArray alloc] initWithAudioUnit:self busType:AUAudioUnitBusTypeOutput busses:@[m_outBus]];
|
m_outs = [[AUAudioUnitBusArray alloc] initWithAudioUnit:self
|
||||||
|
busType:AUAudioUnitBusTypeOutput
|
||||||
|
busses:@[m_outBus]];
|
||||||
|
|
||||||
m_booBackend = std::make_unique<AudioUnitVoiceEngine>();
|
m_booBackend = std::make_unique<AudioUnitVoiceEngine>();
|
||||||
if (!m_booBackend)
|
if (!m_booBackend)
|
||||||
|
@ -177,8 +183,8 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||||
|
|
||||||
m_voxAlloc.emplace(*m_booBackend);
|
m_voxAlloc.emplace(*m_booBackend);
|
||||||
m_engine.emplace(*m_voxAlloc);
|
m_engine.emplace(*m_voxAlloc);
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
{
|
^{
|
||||||
m_filePresenter = [[AudioGroupFilePresenter alloc] initWithAudioGroupClient:self];
|
m_filePresenter = [[AudioGroupFilePresenter alloc] initWithAudioGroupClient:self];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -186,6 +192,12 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)requestAudioGroup:(AudioGroupToken*)group
|
||||||
|
{
|
||||||
|
AudioUnitVoiceEngine& voxEngine = static_cast<AudioUnitVoiceEngine&>(*m_booBackend);
|
||||||
|
voxEngine.m_reqGroup = group;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)allocateRenderResourcesAndReturnError:(NSError **)outError
|
- (BOOL)allocateRenderResourcesAndReturnError:(NSError **)outError
|
||||||
{
|
{
|
||||||
if (![super allocateRenderResourcesAndReturnError:outError])
|
if (![super allocateRenderResourcesAndReturnError:outError])
|
||||||
|
@ -232,11 +244,25 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||||
{
|
{
|
||||||
__block AudioUnitVoiceEngine& voxEngine = static_cast<AudioUnitVoiceEngine&>(*m_booBackend);
|
__block AudioUnitVoiceEngine& voxEngine = static_cast<AudioUnitVoiceEngine&>(*m_booBackend);
|
||||||
__block amuse::Engine& amuseEngine = *m_engine;
|
__block amuse::Engine& amuseEngine = *m_engine;
|
||||||
|
__block std::shared_ptr<amuse::Sequencer> curSeq;
|
||||||
|
|
||||||
return ^AUAudioUnitStatus(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timestamp,
|
return ^AUAudioUnitStatus(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timestamp,
|
||||||
AUAudioFrameCount frameCount, NSInteger outputBusNumber, AudioBufferList* outputData,
|
AUAudioFrameCount frameCount, NSInteger outputBusNumber, AudioBufferList* outputData,
|
||||||
const AURenderEvent* realtimeEventListHead, AURenderPullInputBlock pullInputBlock)
|
const AURenderEvent* realtimeEventListHead, AURenderPullInputBlock pullInputBlock)
|
||||||
{
|
{
|
||||||
|
/* Handle group load request */
|
||||||
|
AudioGroupToken* reqGroup = voxEngine.m_reqGroup;
|
||||||
|
if (voxEngine.m_curGroup != reqGroup)
|
||||||
|
{
|
||||||
|
voxEngine.m_curGroup = reqGroup;
|
||||||
|
if (reqGroup->m_song)
|
||||||
|
{
|
||||||
|
if (curSeq)
|
||||||
|
curSeq->kill();
|
||||||
|
curSeq = amuseEngine.seqPlay(reqGroup->m_id, -1, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Process MIDI events first */
|
/* Process MIDI events first */
|
||||||
if (voxEngine.m_midiReceiver)
|
if (voxEngine.m_midiReceiver)
|
||||||
{
|
{
|
||||||
|
@ -245,9 +271,9 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||||
{
|
{
|
||||||
if (event->eventType == AURenderEventMIDI)
|
if (event->eventType == AURenderEventMIDI)
|
||||||
{
|
{
|
||||||
NSLog(@"MIDI %d %d", event->length, event->data[0]);
|
|
||||||
(*voxEngine.m_midiReceiver)(std::vector<uint8_t>(std::cbegin(event->data),
|
(*voxEngine.m_midiReceiver)(std::vector<uint8_t>(std::cbegin(event->data),
|
||||||
std::cbegin(event->data) + event->length));
|
std::cbegin(event->data) + event->length),
|
||||||
|
event->eventSampleTime / voxEngine.getCurrentSampleRate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,16 @@
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSIndexSet *)browser:(NSBrowser *)browser selectionIndexesForProposedSelection:(NSIndexSet *)proposedSelectionIndexes inColumn:(NSInteger)column
|
||||||
|
{
|
||||||
|
if (column == 2)
|
||||||
|
{
|
||||||
|
AudioGroupToken* token = [browser itemAtRow:proposedSelectionIndexes.firstIndex inColumn:column];
|
||||||
|
[m_audioUnit requestAudioGroup:token];
|
||||||
|
}
|
||||||
|
return proposedSelectionIndexes;
|
||||||
|
}
|
||||||
|
|
||||||
- (id)initWithAudioUnit:(AmuseAudioUnit*)au
|
- (id)initWithAudioUnit:(AmuseAudioUnit*)au
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
@ -152,6 +162,7 @@
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^
|
dispatch_sync(dispatch_get_main_queue(), ^
|
||||||
{
|
{
|
||||||
m_groupBrowser.delegate = m_groupBrowserDelegate;
|
m_groupBrowser.delegate = m_groupBrowserDelegate;
|
||||||
|
[m_groupBrowser loadColumnZero];
|
||||||
});
|
});
|
||||||
return m_audioUnit;
|
return m_audioUnit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "IBackendVoiceAllocator.hpp"
|
#include "IBackendVoiceAllocator.hpp"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
@ -77,9 +76,9 @@ class BooBackendMIDIReader : public IMIDIReader, public boo::IMIDIReader
|
||||||
boo::MIDIDecoder m_decoder;
|
boo::MIDIDecoder m_decoder;
|
||||||
|
|
||||||
bool m_useLock;
|
bool m_useLock;
|
||||||
std::list<std::pair<std::chrono::steady_clock::time_point, std::vector<uint8_t>>> m_queue;
|
std::list<std::pair<double, std::vector<uint8_t>>> m_queue;
|
||||||
std::mutex m_midiMutex;
|
std::mutex m_midiMutex;
|
||||||
void _MIDIReceive(std::vector<uint8_t>&& bytes);
|
void _MIDIReceive(std::vector<uint8_t>&& bytes, double time);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~BooBackendMIDIReader();
|
~BooBackendMIDIReader();
|
||||||
|
|
|
@ -145,7 +145,7 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(const unsigned char* data,
|
||||||
std::pair<Entry, ADPCMParms>& store = m_entries[ent.m_sfxId];
|
std::pair<Entry, ADPCMParms>& store = m_entries[ent.m_sfxId];
|
||||||
ent.setIntoMusyX2(store.first);
|
ent.setIntoMusyX2(store.first);
|
||||||
|
|
||||||
memcpy(&store.second.vadpcm.m_coefs, sampData + ent.m_sampleOff, 256);
|
memmove(&store.second.vadpcm.m_coefs, sampData + ent.m_sampleOff, 256);
|
||||||
store.second.swapBigVADPCM();
|
store.second.swapBigVADPCM();
|
||||||
|
|
||||||
cur += 28;
|
cur += 28;
|
||||||
|
@ -161,7 +161,7 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(const unsigned char* data,
|
||||||
std::pair<Entry, ADPCMParms>& store = m_entries[ent.m_sfxId];
|
std::pair<Entry, ADPCMParms>& store = m_entries[ent.m_sfxId];
|
||||||
ent.setIntoMusyX2(store.first);
|
ent.setIntoMusyX2(store.first);
|
||||||
|
|
||||||
memcpy(&store.second.vadpcm.m_coefs, sampData + ent.m_sampleOff, 256);
|
memmove(&store.second.vadpcm.m_coefs, sampData + ent.m_sampleOff, 256);
|
||||||
store.second.swapBigVADPCM();
|
store.second.swapBigVADPCM();
|
||||||
|
|
||||||
cur += 24;
|
cur += 24;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "amuse/Voice.hpp"
|
#include "amuse/Voice.hpp"
|
||||||
#include "amuse/Submix.hpp"
|
#include "amuse/Submix.hpp"
|
||||||
#include "amuse/Engine.hpp"
|
#include "amuse/Engine.hpp"
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
@ -130,42 +131,46 @@ BooBackendMIDIReader::BooBackendMIDIReader(Engine& engine, const char* name, boo
|
||||||
{
|
{
|
||||||
m_midiIn = voxAlloc.m_booEngine.newRealMIDIIn(dev.first.c_str(),
|
m_midiIn = voxAlloc.m_booEngine.newRealMIDIIn(dev.first.c_str(),
|
||||||
std::bind(&BooBackendMIDIReader::_MIDIReceive, this,
|
std::bind(&BooBackendMIDIReader::_MIDIReceive, this,
|
||||||
std::placeholders::_1));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
if (m_midiIn)
|
if (m_midiIn)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_midiIn = voxAlloc.m_booEngine.newVirtualMIDIIn(std::bind(&BooBackendMIDIReader::_MIDIReceive, this,
|
m_midiIn = voxAlloc.m_booEngine.newVirtualMIDIIn(std::bind(&BooBackendMIDIReader::_MIDIReceive, this,
|
||||||
std::placeholders::_1));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_midiIn = voxAlloc.m_booEngine.newRealMIDIIn(name,
|
m_midiIn = voxAlloc.m_booEngine.newRealMIDIIn(name,
|
||||||
std::bind(&BooBackendMIDIReader::_MIDIReceive, this,
|
std::bind(&BooBackendMIDIReader::_MIDIReceive, this,
|
||||||
std::placeholders::_1));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooBackendMIDIReader::_MIDIReceive(std::vector<uint8_t>&& bytes)
|
void BooBackendMIDIReader::_MIDIReceive(std::vector<uint8_t>&& bytes, double time)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_midiMutex, std::defer_lock_t{});
|
std::unique_lock<std::mutex> lk(m_midiMutex, std::defer_lock_t{});
|
||||||
if (m_useLock)
|
if (m_useLock) lk.lock();
|
||||||
lk.lock();
|
m_queue.emplace_back(time, std::move(bytes));
|
||||||
m_queue.emplace_back(std::chrono::steady_clock::now(), std::move(bytes));
|
#if 0
|
||||||
|
openlog("LogIt", (LOG_CONS|LOG_PERROR|LOG_PID), LOG_DAEMON);
|
||||||
|
syslog(LOG_EMERG, "MIDI receive %f\n", time);
|
||||||
|
closelog();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooBackendMIDIReader::pumpReader(double dt)
|
void BooBackendMIDIReader::pumpReader(double dt)
|
||||||
{
|
{
|
||||||
dt += 0.001; /* Add 1ms to ensure consumer keeps up with producer */
|
dt += 0.001; /* Add 1ms to ensure consumer keeps up with producer */
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lk(m_midiMutex);
|
std::unique_lock<std::mutex> lk(m_midiMutex, std::defer_lock_t{});
|
||||||
|
if (m_useLock) lk.lock();
|
||||||
if (m_queue.empty())
|
if (m_queue.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Determine range of buffer updates within this period */
|
/* Determine range of buffer updates within this period */
|
||||||
auto periodEnd = m_queue.cbegin();
|
auto periodEnd = m_queue.cbegin();
|
||||||
std::chrono::steady_clock::time_point startPt = m_queue.front().first;
|
double startPt = m_queue.front().first;
|
||||||
for (; periodEnd != m_queue.cend() ; ++periodEnd)
|
for (; periodEnd != m_queue.cend() ; ++periodEnd)
|
||||||
{
|
{
|
||||||
double delta = std::chrono::duration_cast<std::chrono::microseconds>
|
double delta = periodEnd->first - startPt;
|
||||||
(periodEnd->first - startPt).count() / 1000000.0;
|
|
||||||
if (delta > dt)
|
if (delta > dt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -176,6 +181,15 @@ void BooBackendMIDIReader::pumpReader(double dt)
|
||||||
/* Dispatch buffers */
|
/* Dispatch buffers */
|
||||||
for (auto it = m_queue.begin() ; it != periodEnd ;)
|
for (auto it = m_queue.begin() ; it != periodEnd ;)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
|
char str[64];
|
||||||
|
sprintf(str, "MIDI %zu %f ", it->second.size(), it->first);
|
||||||
|
for (uint8_t byte : it->second)
|
||||||
|
sprintf(str + strlen(str), "%02X ", byte);
|
||||||
|
openlog("LogIt", (LOG_CONS|LOG_PERROR|LOG_PID), LOG_DAEMON);
|
||||||
|
syslog(LOG_EMERG, "%s\n", str);
|
||||||
|
closelog();
|
||||||
|
#endif
|
||||||
m_decoder.receiveBytes(it->second.cbegin(), it->second.cend());
|
m_decoder.receiveBytes(it->second.cbegin(), it->second.cend());
|
||||||
it = m_queue.erase(it);
|
it = m_queue.erase(it);
|
||||||
}
|
}
|
||||||
|
@ -185,12 +199,22 @@ void BooBackendMIDIReader::noteOff(uint8_t chan, uint8_t key, uint8_t velocity)
|
||||||
{
|
{
|
||||||
for (std::shared_ptr<Sequencer>& seq : m_engine.getActiveSequencers())
|
for (std::shared_ptr<Sequencer>& seq : m_engine.getActiveSequencers())
|
||||||
seq->keyOff(chan, key, velocity);
|
seq->keyOff(chan, key, velocity);
|
||||||
|
#if 0
|
||||||
|
openlog("LogIt", (LOG_CONS|LOG_PERROR|LOG_PID), LOG_DAEMON);
|
||||||
|
syslog(LOG_EMERG, "NoteOff %d", key);
|
||||||
|
closelog();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooBackendMIDIReader::noteOn(uint8_t chan, uint8_t key, uint8_t velocity)
|
void BooBackendMIDIReader::noteOn(uint8_t chan, uint8_t key, uint8_t velocity)
|
||||||
{
|
{
|
||||||
for (std::shared_ptr<Sequencer>& seq : m_engine.getActiveSequencers())
|
for (std::shared_ptr<Sequencer>& seq : m_engine.getActiveSequencers())
|
||||||
seq->keyOn(chan, key, velocity);
|
seq->keyOn(chan, key, velocity);
|
||||||
|
#if 0
|
||||||
|
openlog("LogIt", (LOG_CONS|LOG_PERROR|LOG_PID), LOG_DAEMON);
|
||||||
|
syslog(LOG_EMERG, "NoteOn %d", key);
|
||||||
|
closelog();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooBackendMIDIReader::notePressure(uint8_t /*chan*/, uint8_t /*key*/, uint8_t /*pressure*/)
|
void BooBackendMIDIReader::notePressure(uint8_t /*chan*/, uint8_t /*key*/, uint8_t /*pressure*/)
|
||||||
|
|
|
@ -805,7 +805,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(F
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
{
|
{
|
||||||
proj.reset(new uint8_t[ent.decompSz]);
|
proj.reset(new uint8_t[ent.decompSz]);
|
||||||
memcpy(proj.get(), dataSeg + ent.offset, ent.decompSz);
|
memmove(proj.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -820,7 +820,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(F
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
{
|
{
|
||||||
pool.reset(new uint8_t[ent.decompSz]);
|
pool.reset(new uint8_t[ent.decompSz]);
|
||||||
memcpy(pool.get(), dataSeg + ent.offset, ent.decompSz);
|
memmove(pool.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -835,7 +835,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(F
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
{
|
{
|
||||||
sdir.reset(new uint8_t[ent.decompSz]);
|
sdir.reset(new uint8_t[ent.decompSz]);
|
||||||
memcpy(sdir.get(), dataSeg + ent.offset, ent.decompSz);
|
memmove(sdir.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -850,7 +850,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(F
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
{
|
{
|
||||||
samp.reset(new uint8_t[ent.decompSz]);
|
samp.reset(new uint8_t[ent.decompSz]);
|
||||||
memcpy(samp.get(), dataSeg + ent.offset, ent.decompSz);
|
memmove(samp.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1076,7 +1076,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNN64(F
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
{
|
{
|
||||||
proj.reset(new uint8_t[ent.decompSz]);
|
proj.reset(new uint8_t[ent.decompSz]);
|
||||||
memcpy(proj.get(), dataSeg + ent.offset, ent.decompSz);
|
memmove(proj.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1091,7 +1091,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNN64(F
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
{
|
{
|
||||||
pool.reset(new uint8_t[ent.decompSz]);
|
pool.reset(new uint8_t[ent.decompSz]);
|
||||||
memcpy(pool.get(), dataSeg + ent.offset, ent.decompSz);
|
memmove(pool.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1106,7 +1106,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNN64(F
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
{
|
{
|
||||||
sdir.reset(new uint8_t[ent.decompSz]);
|
sdir.reset(new uint8_t[ent.decompSz]);
|
||||||
memcpy(sdir.get(), dataSeg + ent.offset, ent.decompSz);
|
memmove(sdir.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1121,7 +1121,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNN64(F
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
{
|
{
|
||||||
samp.reset(new uint8_t[ent.decompSz]);
|
samp.reset(new uint8_t[ent.decompSz]);
|
||||||
memcpy(samp.get(), dataSeg + ent.offset, ent.decompSz);
|
memmove(samp.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1279,16 +1279,16 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS2(FILE
|
||||||
head.swapBig();
|
head.swapBig();
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> pool(new uint8_t[head.poolLen]);
|
std::unique_ptr<uint8_t[]> pool(new uint8_t[head.poolLen]);
|
||||||
memcpy(pool.get(), audData.get() + head.poolOff, head.poolLen);
|
memmove(pool.get(), audData.get() + head.poolOff, head.poolLen);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> proj(new uint8_t[head.projLen]);
|
std::unique_ptr<uint8_t[]> proj(new uint8_t[head.projLen]);
|
||||||
memcpy(proj.get(), audData.get() + head.projOff, head.projLen);
|
memmove(proj.get(), audData.get() + head.projOff, head.projLen);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> sdir(new uint8_t[head.sdirLen]);
|
std::unique_ptr<uint8_t[]> sdir(new uint8_t[head.sdirLen]);
|
||||||
memcpy(sdir.get(), audData.get() + head.sdirOff, head.sdirLen);
|
memmove(sdir.get(), audData.get() + head.sdirOff, head.sdirLen);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> samp(new uint8_t[head.sampLen]);
|
std::unique_ptr<uint8_t[]> samp(new uint8_t[head.sampLen]);
|
||||||
memcpy(samp.get(), audData.get() + head.sampOff, head.sampLen);
|
memmove(samp.get(), audData.get() + head.sampOff, head.sampLen);
|
||||||
|
|
||||||
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
|
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
|
||||||
{
|
{
|
||||||
|
@ -1355,7 +1355,7 @@ static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadRS2S
|
||||||
char name[128];
|
char name[128];
|
||||||
snprintf(name, 128, "GroupFile%02u-%u", j, s);
|
snprintf(name, 128, "GroupFile%02u-%u", j, s);
|
||||||
std::unique_ptr<uint8_t[]> song(new uint8_t[sonHead.length]);
|
std::unique_ptr<uint8_t[]> song(new uint8_t[sonHead.length]);
|
||||||
memcpy(song.get(), audData.get() + sonHead.offset, sonHead.length);
|
memmove(song.get(), audData.get() + sonHead.offset, sonHead.length);
|
||||||
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), sonHead.length,
|
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), sonHead.length,
|
||||||
sonHead.groupId, sonHead.setupId));
|
sonHead.groupId, sonHead.setupId));
|
||||||
}
|
}
|
||||||
|
@ -1452,16 +1452,16 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS3(FILE
|
||||||
head.swapBig();
|
head.swapBig();
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> pool(new uint8_t[head.poolLen]);
|
std::unique_ptr<uint8_t[]> pool(new uint8_t[head.poolLen]);
|
||||||
memcpy(pool.get(), audData.get() + head.poolOff, head.poolLen);
|
memmove(pool.get(), audData.get() + head.poolOff, head.poolLen);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> proj(new uint8_t[head.projLen]);
|
std::unique_ptr<uint8_t[]> proj(new uint8_t[head.projLen]);
|
||||||
memcpy(proj.get(), audData.get() + head.projOff, head.projLen);
|
memmove(proj.get(), audData.get() + head.projOff, head.projLen);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> sdir(new uint8_t[head.sdirLen]);
|
std::unique_ptr<uint8_t[]> sdir(new uint8_t[head.sdirLen]);
|
||||||
memcpy(sdir.get(), audData.get() + head.sdirOff, head.sdirLen);
|
memmove(sdir.get(), audData.get() + head.sdirOff, head.sdirLen);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> samp(new uint8_t[head.sampLen]);
|
std::unique_ptr<uint8_t[]> samp(new uint8_t[head.sampLen]);
|
||||||
memcpy(samp.get(), audData.get() + head.sampOff, head.sampLen);
|
memmove(samp.get(), audData.get() + head.sampOff, head.sampLen);
|
||||||
|
|
||||||
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
|
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,7 +92,7 @@ unsigned N64MusyXDecompressFrame(int16_t* out, const uint8_t* in,
|
||||||
adpcm_get_predicted_frame(frame, &in[0x0], &in[0x8], rshift);
|
adpcm_get_predicted_frame(frame, &in[0x0], &in[0x8], rshift);
|
||||||
|
|
||||||
procSamples = (remSamples < 2) ? remSamples : 2;
|
procSamples = (remSamples < 2) ? remSamples : 2;
|
||||||
memcpy(out, frame, 2 * procSamples);
|
memmove(out, frame, 2 * procSamples);
|
||||||
samples += procSamples;
|
samples += procSamples;
|
||||||
remSamples -= procSamples;
|
remSamples -= procSamples;
|
||||||
if (samples == lastSample)
|
if (samples == lastSample)
|
||||||
|
@ -124,7 +124,7 @@ unsigned N64MusyXDecompressFrame(int16_t* out, const uint8_t* in,
|
||||||
adpcm_get_predicted_frame(frame, &in[0x4], &in[0x18], rshift);
|
adpcm_get_predicted_frame(frame, &in[0x4], &in[0x18], rshift);
|
||||||
|
|
||||||
procSamples = (remSamples < 2) ? remSamples : 2;
|
procSamples = (remSamples < 2) ? remSamples : 2;
|
||||||
memcpy(out, frame, 2 * procSamples);
|
memmove(out, frame, 2 * procSamples);
|
||||||
samples += procSamples;
|
samples += procSamples;
|
||||||
remSamples -= procSamples;
|
remSamples -= procSamples;
|
||||||
if (samples == lastSample)
|
if (samples == lastSample)
|
||||||
|
@ -145,7 +145,7 @@ unsigned N64MusyXDecompressFrameRanged(int16_t* out, const uint8_t* in,
|
||||||
int16_t final[64];
|
int16_t final[64];
|
||||||
unsigned procSamples = N64MusyXDecompressFrame(final, in, coefs, firstSample + lastSample);
|
unsigned procSamples = N64MusyXDecompressFrame(final, in, coefs, firstSample + lastSample);
|
||||||
unsigned samples = procSamples - firstSample;
|
unsigned samples = procSamples - firstSample;
|
||||||
memcpy(out, final + firstSample, samples * 2);
|
memmove(out, final + firstSample, samples * 2);
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -474,7 +474,7 @@ size_t Voice::supplyAudio(size_t samples, int16_t* data)
|
||||||
{
|
{
|
||||||
const int16_t* pcm = reinterpret_cast<const int16_t*>(m_curSampleData);
|
const int16_t* pcm = reinterpret_cast<const int16_t*>(m_curSampleData);
|
||||||
remCount = std::min(samplesRem, m_lastSamplePos - m_curSamplePos);
|
remCount = std::min(samplesRem, m_lastSamplePos - m_curSamplePos);
|
||||||
memcpy(data, pcm + m_curSamplePos, remCount * sizeof(int16_t));
|
memmove(data, pcm + m_curSamplePos, remCount * sizeof(int16_t));
|
||||||
decSamples = remCount;
|
decSamples = remCount;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -539,7 +539,7 @@ size_t Voice::supplyAudio(size_t samples, int16_t* data)
|
||||||
{
|
{
|
||||||
const int16_t* pcm = reinterpret_cast<const int16_t*>(m_curSampleData);
|
const int16_t* pcm = reinterpret_cast<const int16_t*>(m_curSampleData);
|
||||||
remCount = std::min(samplesRem, m_lastSamplePos - m_curSamplePos);
|
remCount = std::min(samplesRem, m_lastSamplePos - m_curSamplePos);
|
||||||
memcpy(data, pcm + m_curSamplePos, remCount * sizeof(int16_t));
|
memmove(data, pcm + m_curSamplePos, remCount * sizeof(int16_t));
|
||||||
decSamples = remCount;
|
decSamples = remCount;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue