mirror of https://github.com/AxioDL/amuse.git
Work on AudioUnit
This commit is contained in:
parent
8930e005df
commit
81bd897ec1
|
@ -149,7 +149,7 @@
|
|||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="283" y="305" width="544" height="367"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1366" height="745"/>
|
||||
<view key="contentView" id="9Rk-3e-xVS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="544" height="367"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
|
@ -190,10 +190,10 @@
|
|||
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XHK-NM-ZAP">
|
||||
<rect key="frame" x="0.0" y="28" width="544" height="339"/>
|
||||
<clipView key="contentView" id="cFf-wa-ZPx">
|
||||
<rect key="frame" x="1" y="23" width="542" height="315"/>
|
||||
<rect key="frame" x="1" y="0.0" width="542" height="338"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="jN4-UQ-VfT" viewBased="YES" indentationPerLevel="16" outlineTableColumn="DlG-iE-h1a" id="Vlv-Jw-A4U">
|
||||
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="jN4-UQ-VfT" viewBased="YES" indentationPerLevel="16" outlineTableColumn="DlG-iE-h1a" id="Vlv-Jw-A4U" customClass="DataOutlineView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="542" height="315"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
|
@ -287,7 +287,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="cwa-Vo-ZEb">
|
||||
<rect key="frame" x="159" y="23" width="15" height="-4"/>
|
||||
<rect key="frame" x="159" y="23" width="15" height="4"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<tableHeaderView key="headerView" id="jN4-UQ-VfT">
|
||||
|
@ -372,7 +372,7 @@
|
|||
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4I7-lP-08K">
|
||||
<rect key="frame" x="0.0" y="29" width="544" height="338"/>
|
||||
<clipView key="contentView" id="vf9-4W-0Zi">
|
||||
<rect key="frame" x="1" y="23" width="542" height="314"/>
|
||||
<rect key="frame" x="1" y="0.0" width="542" height="337"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="9pb-bl-sSa" viewBased="YES" id="4nw-rf-Dh4">
|
||||
|
@ -467,7 +467,7 @@
|
|||
<rect key="frame" x="1" y="119" width="223" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="AvT-7G-lW8">
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="AvT-7G-lW8">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
|
@ -542,7 +542,7 @@
|
|||
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aIh-No-CEz">
|
||||
<rect key="frame" x="0.0" y="29" width="544" height="338"/>
|
||||
<clipView key="contentView" id="MzV-rp-Rp8">
|
||||
<rect key="frame" x="1" y="23" width="542" height="314"/>
|
||||
<rect key="frame" x="1" y="0.0" width="542" height="337"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="fQK-tA-ezw" viewBased="YES" id="Frt-wZ-1ZI">
|
||||
|
@ -637,7 +637,7 @@
|
|||
<rect key="frame" x="1" y="119" width="223" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="X6u-4b-0Ia">
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="X6u-4b-0Ia">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
|
@ -685,10 +685,10 @@
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<size key="minSize" width="527" height="365"/>
|
||||
<size key="maxSize" width="541" height="10000000"/>
|
||||
<size key="maxSize" width="544" height="10000000"/>
|
||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="minSize" width="527" height="365"/>
|
||||
<size key="maxSize" width="541" height="10000000"/>
|
||||
<size key="maxSize" width="544" height="10000000"/>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
#import <AudioUnit/AudioUnit.h>
|
||||
#import <CoreAudioKit/AUViewController.h>
|
||||
#import "AudioUnitViewController.hpp"
|
||||
#import "AudioGroupFilePresenter.hpp"
|
||||
|
||||
@class DataOutlineController;
|
||||
@class SamplesTableController;
|
||||
@class SFXTableController;
|
||||
|
||||
@interface MainView : NSView
|
||||
{
|
||||
|
@ -28,6 +33,22 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
{
|
||||
IBOutlet NSWindow* mainWindow;
|
||||
IBOutlet NSOutlineView* dataOutline;
|
||||
IBOutlet NSTableView* sfxTable;
|
||||
IBOutlet NSTableView* samplesTable;
|
||||
IBOutlet NSTextView* creditsView;
|
||||
|
||||
AudioGroupFilePresenter* groupFilePresenter;
|
||||
|
||||
DataOutlineController* dataController;
|
||||
SamplesTableController* samplesController;
|
||||
SFXTableController* sfxController;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface MainTabView : NSTabView
|
||||
{}
|
||||
- (IBAction)selectDataTab:(id)sender;
|
||||
|
@ -55,22 +76,102 @@
|
|||
}
|
||||
@end
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
@interface DataOutlineView : NSOutlineView
|
||||
{
|
||||
IBOutlet NSWindow* mainWindow;
|
||||
IBOutlet NSOutlineView* dataOutline;
|
||||
IBOutlet NSTableView* sfxTable;
|
||||
IBOutlet NSTableView* samplesTable;
|
||||
IBOutlet NSTextView* creditsView;
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DataOutlineView
|
||||
|
||||
- (id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
self = [super initWithFrame:frameRect];
|
||||
[self registerForDraggedTypes:@[(__bridge NSString*)kUTTypeData]];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface DataOutlineController : NSObject <NSOutlineViewDataSource, NSOutlineViewDelegate>
|
||||
{
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DataOutlineController
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@interface SamplesTableController : NSObject <NSTableViewDataSource, NSTableViewDelegate>
|
||||
{
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation SamplesTableController
|
||||
|
||||
- (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn*)tableColumn row:(NSInteger)row
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface SFXTableController : NSObject <NSTableViewDataSource, NSTableViewDelegate>
|
||||
{
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation SFXTableController
|
||||
|
||||
- (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView
|
||||
{
|
||||
}
|
||||
|
||||
- (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn*)tableColumn row:(NSInteger)row
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification*)notification
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
|
||||
[mainWindow.toolbar setSelectedItemIdentifier:@"DataTab"];
|
||||
|
||||
groupFilePresenter = [AudioGroupFilePresenter new];
|
||||
|
||||
dataController = [DataOutlineController new];
|
||||
dataOutline.dataSource = dataController;
|
||||
dataOutline.delegate = dataController;
|
||||
[dataOutline reloadItem:nil reloadChildren:YES];
|
||||
|
||||
samplesController = [SamplesTableController new];
|
||||
samplesTable.dataSource = samplesController;
|
||||
samplesTable.delegate = samplesController;
|
||||
[samplesTable reloadData];
|
||||
|
||||
sfxController = [SFXTableController new];
|
||||
sfxTable.dataSource = sfxController;
|
||||
sfxTable.delegate = sfxController;
|
||||
[sfxTable reloadData];
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __AMUSE_AUDIOUNIT_AUDIOGROUPFILEPRESENTER_HPP__
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
@ -9,29 +10,40 @@
|
|||
|
||||
struct AudioGroupDataCollection
|
||||
{
|
||||
NSURL* m_proj = nullptr; /* Only this member set for single-file containers */
|
||||
NSURL* m_pool = nullptr;
|
||||
NSURL* m_sdir = nullptr;
|
||||
NSURL* m_samp = nullptr;
|
||||
NSURL* m_proj;
|
||||
NSURL* m_pool;
|
||||
NSURL* m_sdir;
|
||||
NSURL* m_samp;
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_projData;
|
||||
std::unique_ptr<uint8_t[]> m_poolData;
|
||||
std::unique_ptr<uint8_t[]> m_sdirData;
|
||||
std::unique_ptr<uint8_t[]> m_sampData;
|
||||
|
||||
bool invalidateURL(NSURL* url);
|
||||
void moveURL(NSURL* oldUrl, NSURL* newUrl);
|
||||
|
||||
std::unique_ptr<uint8_t[]> _coordinateRead(AudioGroupFilePresenter* presenter, size_t& szOut, NSURL* url);
|
||||
bool loadProj(AudioGroupFilePresenter* presenter);
|
||||
bool loadPool(AudioGroupFilePresenter* presenter);
|
||||
bool loadSdir(AudioGroupFilePresenter* presenter);
|
||||
bool loadSamp(AudioGroupFilePresenter* presenter);
|
||||
|
||||
std::unique_ptr<uint8_t[]> coordinateProjRead(AudioGroupFilePresenter* presenter, size_t& szOut);
|
||||
std::unique_ptr<uint8_t[]> coordinatePoolRead(AudioGroupFilePresenter* presenter, size_t& szOut);
|
||||
std::unique_ptr<uint8_t[]> coordinateSdirRead(AudioGroupFilePresenter* presenter, size_t& szOut);
|
||||
std::unique_ptr<uint8_t[]> coordinateSampRead(AudioGroupFilePresenter* presenter, size_t& szOut);
|
||||
AudioGroupDataCollection(NSURL* proj, NSURL* pool, NSURL* sdir, NSURL* samp)
|
||||
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp) {}
|
||||
bool isDataComplete () const {return m_projData && m_poolData && m_sdirData && m_sampData;}
|
||||
};
|
||||
|
||||
@interface AudioGroupFilePresenter : NSObject <NSFilePresenter>
|
||||
@interface AudioGroupFilePresenter : NSObject <NSFilePresenter, NSOutlineViewDataSource>
|
||||
{
|
||||
NSURL* m_groupURL;
|
||||
NSOperationQueue* m_dataQueue;
|
||||
std::map<std::string, AudioGroupDataCollection> m_audioGroupCollections;
|
||||
|
||||
std::map<std::string, AudioGroupDataCollection>::const_iterator m_audioGroupOutlineIt;
|
||||
size_t m_audioGroupOutlineIdx;
|
||||
}
|
||||
|
||||
- (void)update;
|
||||
|
||||
@end
|
||||
|
||||
#endif // __AMUSE_AUDIOUNIT_AUDIOGROUPFILEPRESENTER_HPP__
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "AudioGroupFilePresenter.hpp"
|
||||
#include <athena/FileReader.hpp>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
@implementation AudioGroupFilePresenter
|
||||
|
||||
|
@ -13,36 +14,6 @@
|
|||
return m_dataQueue;
|
||||
}
|
||||
|
||||
bool AudioGroupDataCollection::invalidateURL(NSURL* url)
|
||||
{
|
||||
bool valid = false;
|
||||
if (m_proj)
|
||||
{
|
||||
if ([m_proj isEqual:url])
|
||||
m_proj = nullptr;
|
||||
valid |= m_proj != nullptr;
|
||||
}
|
||||
if (m_pool)
|
||||
{
|
||||
if ([m_pool isEqual:url])
|
||||
m_pool = nullptr;
|
||||
valid |= m_pool != nullptr;
|
||||
}
|
||||
if (m_sdir)
|
||||
{
|
||||
if ([m_sdir isEqual:url])
|
||||
m_sdir = nullptr;
|
||||
valid |= m_sdir != nullptr;
|
||||
}
|
||||
if (m_samp)
|
||||
{
|
||||
if ([m_samp isEqual:url])
|
||||
m_samp = nullptr;
|
||||
valid |= m_samp != nullptr;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
void AudioGroupDataCollection::moveURL(NSURL* oldUrl, NSURL* newUrl)
|
||||
{
|
||||
if (m_proj)
|
||||
|
@ -67,100 +38,109 @@ void AudioGroupDataCollection::moveURL(NSURL* oldUrl, NSURL* newUrl)
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> AudioGroupDataCollection::_coordinateRead(AudioGroupFilePresenter* presenter, size_t& szOut, NSURL* url)
|
||||
{
|
||||
NSFileCoordinator* coord = [[NSFileCoordinator alloc] initWithFilePresenter:presenter];
|
||||
if (!coord)
|
||||
return {};
|
||||
NSError* err;
|
||||
__block std::unique_ptr<uint8_t[]> ret;
|
||||
__block size_t retSz = 0;
|
||||
[coord coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingResolvesSymbolicLink error:&err
|
||||
byAccessor:^(NSURL* newUrl)
|
||||
{
|
||||
athena::io::FileReader r([[newUrl path] UTF8String], 1024 * 32, false);
|
||||
if (r.hasError())
|
||||
return;
|
||||
retSz = r.length();
|
||||
ret = r.readUBytes(retSz);
|
||||
}];
|
||||
szOut = retSz;
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> AudioGroupDataCollection::coordinateProjRead(AudioGroupFilePresenter* presenter, size_t& szOut)
|
||||
bool AudioGroupDataCollection::loadProj(AudioGroupFilePresenter* presenter)
|
||||
{
|
||||
if (!m_proj)
|
||||
return {};
|
||||
return _coordinateRead(presenter, szOut, m_proj);
|
||||
return false;
|
||||
NSFileCoordinator* coord = [[NSFileCoordinator alloc] initWithFilePresenter:presenter];
|
||||
if (!coord)
|
||||
return false;
|
||||
NSError* err;
|
||||
__block std::unique_ptr<uint8_t[]>& ret = m_projData;
|
||||
[coord coordinateReadingItemAtURL:m_proj
|
||||
options:NSFileCoordinatorReadingResolvesSymbolicLink error:&err
|
||||
byAccessor:^(NSURL* newUrl)
|
||||
{
|
||||
athena::io::FileReader r([[newUrl path] UTF8String], 1024 * 32, false);
|
||||
if (r.hasError())
|
||||
return;
|
||||
ret = r.readUBytes(r.length());
|
||||
}];
|
||||
return m_projData.operator bool();
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> AudioGroupDataCollection::coordinatePoolRead(AudioGroupFilePresenter* presenter, size_t& szOut)
|
||||
bool AudioGroupDataCollection::loadPool(AudioGroupFilePresenter* presenter)
|
||||
{
|
||||
if (!m_pool)
|
||||
return {};
|
||||
return _coordinateRead(presenter, szOut, m_pool);
|
||||
return false;
|
||||
NSFileCoordinator* coord = [[NSFileCoordinator alloc] initWithFilePresenter:presenter];
|
||||
if (!coord)
|
||||
return false;
|
||||
NSError* err;
|
||||
__block std::unique_ptr<uint8_t[]>& ret = m_poolData;
|
||||
[coord coordinateReadingItemAtURL:m_pool
|
||||
options:NSFileCoordinatorReadingResolvesSymbolicLink error:&err
|
||||
byAccessor:^(NSURL* newUrl)
|
||||
{
|
||||
athena::io::FileReader r([[newUrl path] UTF8String], 1024 * 32, false);
|
||||
if (r.hasError())
|
||||
return;
|
||||
ret = r.readUBytes(r.length());
|
||||
}];
|
||||
return m_poolData.operator bool();
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> AudioGroupDataCollection::coordinateSdirRead(AudioGroupFilePresenter* presenter, size_t& szOut)
|
||||
bool AudioGroupDataCollection::loadSdir(AudioGroupFilePresenter* presenter)
|
||||
{
|
||||
if (!m_sdir)
|
||||
return {};
|
||||
return _coordinateRead(presenter, szOut, m_sdir);
|
||||
return false;
|
||||
NSFileCoordinator* coord = [[NSFileCoordinator alloc] initWithFilePresenter:presenter];
|
||||
if (!coord)
|
||||
return false;
|
||||
NSError* err;
|
||||
__block std::unique_ptr<uint8_t[]>& ret = m_sdirData;
|
||||
[coord coordinateReadingItemAtURL:m_sdir
|
||||
options:NSFileCoordinatorReadingResolvesSymbolicLink error:&err
|
||||
byAccessor:^(NSURL* newUrl)
|
||||
{
|
||||
athena::io::FileReader r([[newUrl path] UTF8String], 1024 * 32, false);
|
||||
if (r.hasError())
|
||||
return;
|
||||
ret = r.readUBytes(r.length());
|
||||
}];
|
||||
return m_sdirData.operator bool();
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> AudioGroupDataCollection::coordinateSampRead(AudioGroupFilePresenter* presenter, size_t& szOut)
|
||||
bool AudioGroupDataCollection::loadSamp(AudioGroupFilePresenter* presenter)
|
||||
{
|
||||
if (!m_samp)
|
||||
return {};
|
||||
return _coordinateRead(presenter, szOut, m_samp);
|
||||
}
|
||||
|
||||
- (void)accommodatePresentedSubitemDeletionAtURL:(NSURL*)url completionHandler:(void (^)(NSError* errorOrNil))completionHandler
|
||||
{
|
||||
for (auto it = m_audioGroupCollections.begin() ; it != m_audioGroupCollections.end() ;)
|
||||
{
|
||||
std::pair<const std::string, AudioGroupDataCollection>& pair = *it;
|
||||
if (pair.second.invalidateURL(url))
|
||||
{
|
||||
it = m_audioGroupCollections.erase(it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
completionHandler(nil);
|
||||
return false;
|
||||
NSFileCoordinator* coord = [[NSFileCoordinator alloc] initWithFilePresenter:presenter];
|
||||
if (!coord)
|
||||
return false;
|
||||
NSError* err;
|
||||
__block std::unique_ptr<uint8_t[]>& ret = m_sampData;
|
||||
[coord coordinateReadingItemAtURL:m_samp
|
||||
options:NSFileCoordinatorReadingResolvesSymbolicLink error:&err
|
||||
byAccessor:^(NSURL* newUrl)
|
||||
{
|
||||
athena::io::FileReader r([[newUrl path] UTF8String], 1024 * 32, false);
|
||||
if (r.hasError())
|
||||
return;
|
||||
ret = r.readUBytes(r.length());
|
||||
}];
|
||||
return m_sampData.operator bool();
|
||||
}
|
||||
|
||||
- (void)presentedSubitemDidAppearAtURL:(NSURL*)url
|
||||
{
|
||||
NSString* path = [url path];
|
||||
if (!path)
|
||||
return;
|
||||
NSURL* dir = nil;
|
||||
if ([url.lastPathComponent isEqualToString:@"proj"] ||
|
||||
[url.lastPathComponent isEqualToString:@"pool"] ||
|
||||
[url.lastPathComponent isEqualToString:@"sdir"] ||
|
||||
[url.lastPathComponent isEqualToString:@"samp"])
|
||||
dir = url.baseURL;
|
||||
|
||||
NSString* extension = [url pathExtension];
|
||||
NSString* lastComp = [url lastPathComponent];
|
||||
lastComp = [lastComp substringToIndex:[lastComp length] - [extension length]];
|
||||
AudioGroupDataCollection& collection = m_audioGroupCollections[[lastComp UTF8String]];
|
||||
|
||||
if ([extension isEqualToString:@"pro"] || [extension isEqualToString:@"proj"])
|
||||
auto search = m_audioGroupCollections.find(dir.lastPathComponent.UTF8String);
|
||||
if (search == m_audioGroupCollections.end())
|
||||
{
|
||||
collection.m_proj = url;
|
||||
}
|
||||
else if ([extension isEqualToString:@"poo"] || [extension isEqualToString:@"pool"])
|
||||
{
|
||||
collection.m_pool = url;
|
||||
}
|
||||
else if ([extension isEqualToString:@"sdi"] || [extension isEqualToString:@"sdir"])
|
||||
{
|
||||
collection.m_sdir = url;
|
||||
}
|
||||
else if ([extension isEqualToString:@"sam"] || [extension isEqualToString:@"samp"])
|
||||
{
|
||||
collection.m_samp = url;
|
||||
}
|
||||
else
|
||||
{
|
||||
collection.m_proj = url;
|
||||
search =
|
||||
m_audioGroupCollections.emplace(dir.lastPathComponent.UTF8String,
|
||||
AudioGroupDataCollection{
|
||||
[dir URLByAppendingPathComponent:@"proj"],
|
||||
[dir URLByAppendingPathComponent:@"pool"],
|
||||
[dir URLByAppendingPathComponent:@"sdir"],
|
||||
[dir URLByAppendingPathComponent:@"samp"]}).first;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,6 +153,71 @@ std::unique_ptr<uint8_t[]> AudioGroupDataCollection::coordinateSampRead(AudioGro
|
|||
}
|
||||
}
|
||||
|
||||
- (NSInteger)outlineView:(NSOutlineView*)outlineView numberOfChildrenOfItem:(nullable id)item
|
||||
{
|
||||
if (!item)
|
||||
return m_audioGroupCollections.size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (id)outlineView:(NSOutlineView*)outlineView child:(NSInteger)index ofItem:(nullable id)item
|
||||
{
|
||||
if (!item)
|
||||
{
|
||||
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)outlineView:(NSOutlineView*)outlineView isItemExpandable:(id)item
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)update
|
||||
{
|
||||
NSFileCoordinator* coord = [[NSFileCoordinator alloc] initWithFilePresenter:self];
|
||||
if (!coord)
|
||||
return;
|
||||
NSError* coordErr;
|
||||
__block NSError* managerErr;
|
||||
__block std::map<std::string, AudioGroupDataCollection>& theMap = m_audioGroupCollections;
|
||||
[coord coordinateReadingItemAtURL:m_groupURL options:NSFileCoordinatorReadingResolvesSymbolicLink error:&coordErr
|
||||
byAccessor:^(NSURL* newUrl)
|
||||
{
|
||||
NSFileManager* fman = [NSFileManager defaultManager];
|
||||
NSArray<NSURL*>* contents =
|
||||
[fman contentsOfDirectoryAtURL:newUrl
|
||||
includingPropertiesForKeys:@[NSURLIsDirectoryKey]
|
||||
options:NSDirectoryEnumerationSkipsSubdirectoryDescendants |
|
||||
NSDirectoryEnumerationSkipsHiddenFiles
|
||||
error:&managerErr];
|
||||
if (!contents)
|
||||
return;
|
||||
|
||||
for (NSURL* path in contents)
|
||||
{
|
||||
NSNumber* isDir;
|
||||
[path getResourceValue:&isDir forKey:NSURLIsDirectoryKey error:nil];
|
||||
|
||||
if (isDir.boolValue)
|
||||
{
|
||||
auto search = theMap.find(path.lastPathComponent.UTF8String);
|
||||
if (search == theMap.end())
|
||||
{
|
||||
search =
|
||||
theMap.emplace(path.lastPathComponent.UTF8String,
|
||||
AudioGroupDataCollection{
|
||||
[path URLByAppendingPathComponent:@"proj"],
|
||||
[path URLByAppendingPathComponent:@"pool"],
|
||||
[path URLByAppendingPathComponent:@"sdir"],
|
||||
[path URLByAppendingPathComponent:@"samp"]}).first;
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
m_groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.io.github.axiodl.Amuse.AudioGroups"];
|
||||
|
@ -180,6 +225,7 @@ std::unique_ptr<uint8_t[]> AudioGroupDataCollection::coordinateSampRead(AudioGro
|
|||
return nil;
|
||||
m_dataQueue = [NSOperationQueue new];
|
||||
[NSFileCoordinator addFilePresenter:self];
|
||||
[self update];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ Sequencer::Sequencer(Engine& engine, const AudioGroup& group, int groupId,
|
|||
m_midiSetup = it->second->data();
|
||||
|
||||
m_submix = m_engine.addSubmix(smx);
|
||||
m_submix->makeReverbHi(0.2f, 1.f, 1.f, 0.5f, 0.f, 0.f);
|
||||
m_submix->makeReverbHi(0.2f, 0.65f, 1.f, 0.5f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
Sequencer::ChannelState::~ChannelState()
|
||||
|
|
Loading…
Reference in New Issue