mirror of
https://github.com/AxioDL/amuse.git
synced 2025-12-09 21:47:53 +00:00
Initial working AudioUnit integration
This commit is contained in:
@@ -127,11 +127,12 @@ struct AudioGroupCollection
|
||||
{
|
||||
@public
|
||||
NSString* m_name;
|
||||
int m_id;
|
||||
const amuse::SongGroupIndex* m_song;
|
||||
const amuse::SFXGroupIndex* m_sfx;
|
||||
}
|
||||
- (id)initWithName:(NSString*)name songGroup:(const amuse::SongGroupIndex*)group;
|
||||
- (id)initWithName:(NSString*)name sfxGroup:(const amuse::SFXGroupIndex*)group;
|
||||
- (id)initWithName:(NSString*)name id:(int)gid songGroup:(const amuse::SongGroupIndex*)group;
|
||||
- (id)initWithName:(NSString*)name id:(int)gid sfxGroup:(const amuse::SFXGroupIndex*)group;
|
||||
@end
|
||||
|
||||
@interface AudioGroupFilePresenter : NSObject <NSFilePresenter, NSOutlineViewDataSource, NSOutlineViewDelegate>
|
||||
@@ -139,7 +140,6 @@ struct AudioGroupCollection
|
||||
@public
|
||||
id<AudioGroupClient> m_audioGroupClient;
|
||||
NSURL* m_groupURL;
|
||||
NSOperationQueue* m_dataQueue;
|
||||
std::map<std::string, std::unique_ptr<AudioGroupCollection>> m_audioGroupCollections;
|
||||
std::vector<std::map<std::string, std::unique_ptr<AudioGroupCollection>>::iterator> m_filterAudioGroupCollections;
|
||||
NSOutlineView* m_lastOutlineView;
|
||||
|
||||
@@ -53,18 +53,20 @@ static std::string StrToLower(const std::string& str)
|
||||
@end
|
||||
|
||||
@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];
|
||||
m_name = name;
|
||||
m_song = group;
|
||||
m_id = gid;
|
||||
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];
|
||||
m_name = name;
|
||||
m_sfx = group;
|
||||
m_id = gid;
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
@@ -78,7 +80,7 @@ static std::string StrToLower(const std::string& str)
|
||||
|
||||
- (NSOperationQueue*)presentedItemOperationQueue
|
||||
{
|
||||
return m_dataQueue;
|
||||
return [NSOperationQueue mainQueue];
|
||||
}
|
||||
|
||||
AudioGroupCollection::AudioGroupCollection(NSURL* url)
|
||||
@@ -305,7 +307,8 @@ bool AudioGroupDataCollection::_indexData(AudioGroupFilePresenter* presenter)
|
||||
for (const auto& pair : sortGroups)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
- (void)presentedSubitemDidAppearAtURL:(NSURL*)url
|
||||
- (void)presentedSubitemDidChangeAtURL:(NSURL *)url
|
||||
{
|
||||
if ([url.lastPathComponent isEqualToString:@"proj"] ||
|
||||
[url.lastPathComponent isEqualToString:@"pool"] ||
|
||||
[url.lastPathComponent isEqualToString:@"sdir"] ||
|
||||
[url.lastPathComponent isEqualToString:@"samp"])
|
||||
size_t relComps = url.pathComponents.count - m_groupURL.pathComponents.count;
|
||||
if (relComps <= 1)
|
||||
[self update];
|
||||
}
|
||||
|
||||
@@ -850,7 +852,6 @@ bool AudioGroupDataCollection::loadMeta(AudioGroupFilePresenter* presenter)
|
||||
m_groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.io.github.axiodl.Amuse.AudioGroups"];
|
||||
if (!m_groupURL)
|
||||
return nil;
|
||||
m_dataQueue = [NSOperationQueue new];
|
||||
[NSFileCoordinator addFilePresenter:self];
|
||||
[self update];
|
||||
return self;
|
||||
|
||||
@@ -49,6 +49,7 @@ void RegisterAudioUnit();
|
||||
- (nullable id)initWithComponentDescription:(AudioComponentDescription)componentDescription
|
||||
error:(NSError * __nullable * __nonnull)outError
|
||||
viewController:(AudioUnitViewController* __nonnull)vc;
|
||||
- (void)requestAudioGroup:(AudioGroupToken*)group;
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,8 @@ static logvisor::Module Log("amuse::AudioUnitBackend");
|
||||
|
||||
struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||
{
|
||||
AudioGroupToken* m_reqGroup = nullptr;
|
||||
AudioGroupToken* m_curGroup = nullptr;
|
||||
std::vector<float> m_interleavedBuf;
|
||||
std::vector<std::unique_ptr<float[]>> m_renderBufs;
|
||||
size_t m_renderFrames = 0;
|
||||
@@ -137,6 +139,8 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double getCurrentSampleRate() const {return m_mixInfo.m_sampleRate;}
|
||||
};
|
||||
|
||||
@implementation AmuseAudioUnit
|
||||
@@ -165,7 +169,9 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||
//m_outBus.supportedChannelCounts = @[@1,@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>();
|
||||
if (!m_booBackend)
|
||||
@@ -177,8 +183,8 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||
|
||||
m_voxAlloc.emplace(*m_booBackend);
|
||||
m_engine.emplace(*m_voxAlloc);
|
||||
dispatch_sync(dispatch_get_main_queue(), ^
|
||||
{
|
||||
dispatch_sync(dispatch_get_main_queue(),
|
||||
^{
|
||||
m_filePresenter = [[AudioGroupFilePresenter alloc] initWithAudioGroupClient:self];
|
||||
});
|
||||
|
||||
@@ -186,6 +192,12 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)requestAudioGroup:(AudioGroupToken*)group
|
||||
{
|
||||
AudioUnitVoiceEngine& voxEngine = static_cast<AudioUnitVoiceEngine&>(*m_booBackend);
|
||||
voxEngine.m_reqGroup = group;
|
||||
}
|
||||
|
||||
- (BOOL)allocateRenderResourcesAndReturnError:(NSError **)outError
|
||||
{
|
||||
if (![super allocateRenderResourcesAndReturnError:outError])
|
||||
@@ -232,11 +244,25 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||
{
|
||||
__block AudioUnitVoiceEngine& voxEngine = static_cast<AudioUnitVoiceEngine&>(*m_booBackend);
|
||||
__block amuse::Engine& amuseEngine = *m_engine;
|
||||
__block std::shared_ptr<amuse::Sequencer> curSeq;
|
||||
|
||||
return ^AUAudioUnitStatus(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timestamp,
|
||||
AUAudioFrameCount frameCount, NSInteger outputBusNumber, AudioBufferList* outputData,
|
||||
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 */
|
||||
if (voxEngine.m_midiReceiver)
|
||||
{
|
||||
@@ -245,9 +271,9 @@ struct AudioUnitVoiceEngine : boo::BaseAudioVoiceEngine
|
||||
{
|
||||
if (event->eventType == AURenderEventMIDI)
|
||||
{
|
||||
NSLog(@"MIDI %d %d", event->length, event->data[0]);
|
||||
(*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;
|
||||
}
|
||||
|
||||
- (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
|
||||
{
|
||||
self = [super init];
|
||||
@@ -152,6 +162,7 @@
|
||||
dispatch_sync(dispatch_get_main_queue(), ^
|
||||
{
|
||||
m_groupBrowser.delegate = m_groupBrowserDelegate;
|
||||
[m_groupBrowser loadColumnZero];
|
||||
});
|
||||
return m_audioUnit;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user