Work on AudioUnit

This commit is contained in:
Jack Andersen 2016-06-02 16:53:52 -10:00
parent 8930e005df
commit 81bd897ec1
5 changed files with 291 additions and 132 deletions

View File

@ -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"/>

View File

@ -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

View File

@ -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__

View File

@ -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)
bool AudioGroupDataCollection::loadProj(AudioGroupFilePresenter* presenter)
{
if (!m_proj)
return false;
NSFileCoordinator* coord = [[NSFileCoordinator alloc] initWithFilePresenter:presenter];
if (!coord)
return {};
return false;
NSError* err;
__block std::unique_ptr<uint8_t[]> ret;
__block size_t retSz = 0;
[coord coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingResolvesSymbolicLink error:&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;
retSz = r.length();
ret = r.readUBytes(retSz);
ret = r.readUBytes(r.length());
}];
szOut = retSz;
return std::move(ret);
return m_projData.operator bool();
}
std::unique_ptr<uint8_t[]> AudioGroupDataCollection::coordinateProjRead(AudioGroupFilePresenter* presenter, size_t& szOut)
{
if (!m_proj)
return {};
return _coordinateRead(presenter, szOut, m_proj);
}
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
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)
{
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);
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;
}

View File

@ -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()