Change order and method of build effect chains for inputs: input -> converter -> delayX5 -> effects -> downmixer

This commit is contained in:
Zakk 2020-02-22 03:13:05 -05:00
parent 6931cc3aa2
commit f2c879b99b
8 changed files with 159 additions and 134 deletions

View file

@ -450,7 +450,9 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
}
NSNumber *trackOutBus = outputTrack.outputBus;
[self.encodeMixer disconnectInputBus:input.effectsHead.connectedToBus fromOutputBus:trackOutBus.unsignedIntValue];
CAMultiAudioConnection *inputConn = [self.graph findOutputConnection:input.headNode forNode:self.encodeMixer onBus:0];
[self.encodeMixer disconnectInputBus:inputConn.bus fromOutputBus:trackOutBus.unsignedIntValue];
[input.outputTracks removeObjectForKey:outputTrack.uuid];
return YES;
}
@ -470,10 +472,10 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
NSNumber *trackOutBus = outputTrack.outputBus;
NSLog(@"EFFECT HEAD %@ ON BUS %d -> BUS %d", input.effectsHead, input.effectsHead.connectedToBus, trackOutBus.unsignedIntValue);
[self.encodeMixer connectInputBus:input.effectsHead.connectedToBus toOutputBus:trackOutBus.unsignedIntValue];
[input.outputTracks setObject:outputTrack forKey:outputTrack.uuid];
CAMultiAudioConnection *inputConn = [self.graph findOutputConnection:input.headNode forNode:self.encodeMixer onBus:0];
[self.encodeMixer connectInputBus:inputConn.bus toOutputBus:trackOutBus.unsignedIntValue];
CAMultiAudioOutputTrackConnection *trackConn = [[CAMultiAudioOutputTrackConnection alloc] initWithTrack:outputTrack inBus:inputConn.bus];
[input.outputTracks setObject:trackConn forKey:outputTrack.uuid];
return YES;
}
@ -540,8 +542,9 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
[self.graph addNode:encNode];
[self.graph connectNode:self.encodeMixer toNode:encNode];
[self.graph connectNode:encNode toNode:self.previewMixer];
[self.previewMixer setVolumeOnInputBus:encNode.connectedToBus volume:0.0f];
CAMultiAudioConnection *eConn = [self.graph inputConnection:encNode forBus:0];
[self.previewMixer setVolumeOnInputBus:eConn.bus volume:0.0f];
CAMultiAudioConnection *silenceConn = [self.graph findOutputConnection:self.silentNode forNode:self.encodeMixer onBus:0];
[self.encodeMixer setVolumeOnOutputBus:eConn.bus volume:1.0f];

View file

@ -43,6 +43,9 @@
-(NSArray *)connectedInputBusses:(CAMultiAudioNode *)node;
-(NSArray *)connectedOutputBusses:(CAMultiAudioNode *)node;
-(CAMultiAudioConnection *)findOutputConnection:(CAMultiAudioNode *)node forNode:(CAMultiAudioNode *)forNode onBus:(UInt32)outBus;
-(bool)connectNode:(CAMultiAudioNode *)node usingConnections:(NSArray *)connections outBus:(UInt32)outBus format:(AVAudioFormat *)format;
-(bool)connectNode:(CAMultiAudioNode *)node usingConnections:(NSArray *)connections outBus:(UInt32)outBus;

View file

@ -204,6 +204,33 @@
return YES;
}
-(bool)connectNode:(CAMultiAudioNode *)node usingConnections:(NSArray *)connections outBus:(UInt32)outBus
{
return [self connectNode:node usingConnections:connections outBus:outBus format:self.audioFormat];
}
-(bool)connectNode:(CAMultiAudioNode *)node usingConnections:(NSArray *)connections outBus:(UInt32)outBus format:(AVAudioFormat *)format
{
if (!_graphInst)
{
NSLog(@"ConnectNode: No AUGraph!");
return NO;
}
if (!node)
{
return NO;
}
for(CAMultiAudioConnection *conn in connections)
{
[self connectNode:node toNode:conn.node format:format inBus:conn.bus outBus:outBus];
}
return YES;
}
-(bool)connectNode:(CAMultiAudioNode *)node toNode:(CAMultiAudioNode *)toNode
{

View file

@ -162,42 +162,16 @@
}
self.downMixer = [[CAMultiAudioDownmixer alloc] initWithInputChannels:self.channelCount];
if (![self.graph addNode:self.downMixer])
{
[self teardownGraph];
return NO;
}
self.downMixer.muted = NO;
self.downMixer.volume = 1.0f;
CAMultiAudioNode *connectTo = self.converterNode;
if (!connectTo)
{
connectTo = self.downMixer;
}
if(![self.graph connectNode:self toNode:connectTo format:self.inputFormat])
if (![self.graph connectNode:self toNode:self.converterNode format:self.inputFormat])
{
[self teardownGraph];
return NO;
}
if (self.converterNode)
{
if(![self.graph connectNode:self.converterNode toNode:self.downMixer])
{
[self teardownGraph];
return NO;
}
}
AVAudioFormat *useFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:self.graph.audioFormat.sampleRate channelLayout:self.inputFormat.channelLayout];
CAMultiAudioDelay *delayNode;
CAMultiAudioNode *connectNode = self.downMixer;
CAMultiAudioNode *connectNode = self.converterNode;
for(int i=0; i < 5; i++)
{
@ -210,7 +184,7 @@
[self teardownGraph];
return NO;
}
ret = [self.graph connectNode:connectNode toNode:delayNode];
ret = [self.graph connectNode:connectNode toNode:delayNode format:useFormat];
if (!ret)
{
@ -225,30 +199,34 @@
[self.delayNodes addObject:delayNode];
}
self.effectsHead = connectNode;
[self.downMixer connectInputBus:0 toOutputBus:0];
self.headNode = delayNode;
self.effectsHead = delayNode;
return YES;
}
-(void)rebuildEffectChain
-(void)setupDownmixer
{
[super rebuildEffectChain];
[self.graph connectNode:self.effectsHead toNode:self.downMixer];
AVAudioFormat *useFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:self.graph.audioFormat.sampleRate channelLayout:self.inputFormat.channelLayout];
self.downMixer = [[CAMultiAudioDownmixer alloc] initWithInputChannels:useFormat.channelCount];
[self.graph addNode:self.downMixer];
[self.graph connectNode:self.headNode toNode:self.downMixer format:useFormat];
self.headNode = self.downMixer;
self.downMixer.volume = 1.0f;
self.downMixer.muted = NO;
[self.downMixer connectInputBus:0 toOutputBus:0];
}
-(void)setupEffectsChain
{
[self setupGraph];
//self.effectsHead = self;
// [super setupEffectsChain];
self.headNode = self.effectsHead;
//[self.converterNode generateTone];
[super setupEffectsChain];
[self setupDownmixer];
}

View file

@ -40,8 +40,6 @@
@property (assign) float volume;
@property (assign) bool muted;
@property (assign) bool enabled;
@property (readonly) CAMultiAudioNode *connectedTo;
@property (readonly) UInt32 connectedToBus;
-(instancetype)initWithSubType:(OSType)subType unitType:(OSType)unitType;
-(instancetype)initWithSubType:(OSType)subType unitType:(OSType)unitType manufacturer:(OSType)manufacturer;
@ -75,6 +73,7 @@
AudioComponentDescription unitDescr;
CAMultiAudioVolumeAnimation *_volumeAnimation;
NSMutableArray *_currentEffectChain;
}
@property (assign) AUNode node;
@ -97,7 +96,6 @@
@property (strong) NSMutableDictionary *outputConnections;
@property (readonly) CAMultiAudioNode *connectedTo;
@property (readonly) UInt32 connectedToBus;
@property (assign) float volume;
@ -118,6 +116,8 @@
-(void)addEffect:(CAMultiAudioNode *)effect;
-(void)addEffect:(CAMultiAudioNode *)effect atIndex:(NSUInteger)idx;
-(void)generateTone;
-(void)reset;
@end

View file

@ -33,8 +33,6 @@ UInt32 inNumberFrames,
@synthesize volume = _volume;
@synthesize muted = _muted;
@synthesize enabled = _enabled;
@synthesize connectedTo = _connectedTo;
@synthesize connectedToBus = _connectedToBus;
-(instancetype)init
{
@ -63,6 +61,7 @@ UInt32 inNumberFrames,
self.nodeUID = [[NSUUID UUID] UUIDString];
self.inputConnections = [NSMutableDictionary dictionary];
self.outputConnections = [NSMutableDictionary dictionary];
_currentEffectChain = [NSMutableArray array];
}
return self;
@ -332,14 +331,9 @@ UInt32 inNumberFrames,
-(void)nodeConnected:(CAMultiAudioNode *)toNode inBus:(UInt32)inBus outBus:(UInt32)outBus
{
if (outBus == 0)
{
_connectedTo = toNode;
_connectedToBus = inBus;
}
return;
}
@ -443,60 +437,63 @@ UInt32 inNumberFrames,
-(void)rebuildEffectChain
{
//Disconnect every node from effectsHead -> headNode (including headNode) and then reconnect everything in effectchain array
bool restoreHeadNode = NO;
NSArray *outConnections = nil;
CAMultiAudioNode *lastEffect = _currentEffectChain.lastObject;
AVAudioFormat *useFormat = [self.effectsHead outputFormatForBus:0];
if (lastEffect)
{
outConnections = [self.graph outputConnections:lastEffect forBus:0];
if (lastEffect == self.headNode)
{
restoreHeadNode = YES;
}
} else {
outConnections = [self.graph outputConnections:self.effectsHead forBus:0];
}
[self.effectsHead.graph disconnectNodeOutput:self.effectsHead];
for (CAMultiAudioNode *currNode in _currentEffectChain)
{
if (currNode && currNode.graph)
{
[currNode.graph disconnectNode:currNode];
[currNode.graph removeNode:currNode];
}
}
[_currentEffectChain removeAllObjects];
CAMultiAudioNode *currNode = self.effectsHead;
CAMultiAudioNode *headConn;
while (currNode && currNode != self.headNode)
{
CAMultiAudioNode *connNode = currNode.connectedTo;
[self.graph disconnectNode:currNode];
if (currNode.deleteNode)
{
[self.graph removeNode:currNode];
}
currNode = connNode;
}
if (currNode) //This is headNode
{
headConn = currNode.connectedTo;
[self.graph disconnectNode:currNode];
if (currNode.deleteNode)
{
[self.graph removeNode:currNode];
}
self.headNode = self.effectsHead;
}
currNode = nil;
currNode = self.effectsHead;
for (CAMultiAudioNode *eNode in self.effectChain)
{
[self.graph addNode:eNode];
[self.graph connectNode:currNode toNode:eNode];
[self.graph connectNode:currNode toNode:eNode format:useFormat];
[_currentEffectChain addObject:eNode];
currNode = eNode;
}
if (headConn && currNode)
if (outConnections && outConnections.count > 0)
{
[self.graph connectNode:currNode toNode:headConn];
[currNode.graph connectNode:currNode usingConnections:outConnections outBus:0 format:useFormat];
}
if (currNode)
if (restoreHeadNode)
{
self.headNode = currNode;
} else {
self.headNode = self.effectsHead;
}
//CAShow(self.graph.graphInst);
}
-(void)addEffect:(CAMultiAudioNode *)effect;
@ -569,6 +566,12 @@ UInt32 inNumberFrames,
}
-(void)reset
{
AudioUnitReset(self.audioUnit, kAudioUnitScope_Global, 0);
AudioUnitUninitialize(self.audioUnit);
AudioUnitInitialize(self.audioUnit);
}
-(void) dealloc
{
if (self.graph)

View file

@ -57,9 +57,20 @@
-(void)openAddTrackPopover:(id)sender sourceRect:(NSRect)sourceRect
{
[self buildTrackMenu];
NSInteger midItem = 0;
NSInteger midItem = _tracksMenu.itemArray.count/2;
if (_tracksMenu.itemArray.count == 0)
{
return;
}
if (_tracksMenu.itemArray.count > 2)
{
midItem = _tracksMenu.itemArray.count/2;
}
NSPoint popupPoint = NSMakePoint(NSMaxY(sourceRect), NSMidY(sourceRect));
[_tracksMenu popUpMenuPositioningItem:[_tracksMenu itemAtIndex:midItem] atLocation:popupPoint inView:sender];
}
@ -99,7 +110,7 @@
self.audioNode = node;
self.downMixer = node.downMixer;
NSSortDescriptor *nameSort = [NSSortDescriptor sortDescriptorWithKey:@"value.name" ascending:YES comparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSSortDescriptor *nameSort = [NSSortDescriptor sortDescriptorWithKey:@"value.outputTrack.name" ascending:YES comparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSString *name1 = obj1;
NSString *name2 = obj2;

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15505"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -20,26 +20,26 @@
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="684" height="427"/>
<rect key="screenRect" x="0.0" y="0.0" width="3440" height="1417"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="684" height="427"/>
<view key="contentView" misplaced="YES" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="684" height="404"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView autohidesScrollers="YES" horizontalLineScroll="74" horizontalPageScroll="10" verticalLineScroll="74" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tVp-xm-zat">
<rect key="frame" x="258" y="-1" width="427" height="392"/>
<rect key="frame" x="258" y="-1" width="427" height="345"/>
<clipView key="contentView" id="p64-r1-trE">
<rect key="frame" x="1" y="0.0" width="425" height="391"/>
<rect key="frame" x="1" y="0.0" width="425" height="344"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnReordering="NO" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="72" headerView="Vgl-NM-EJm" viewBased="YES" id="C8k-GN-Boe">
<rect key="frame" x="0.0" y="0.0" width="425" height="368"/>
<autoresizingMask key="autoresizingMask"/>
<rect key="frame" x="0.0" y="0.0" width="425" height="321"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="88" minWidth="40" maxWidth="1000" id="FQ8-QY-ESB">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Input Channels">
<font key="font" metaFont="smallSystem"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -55,7 +55,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="3fF-18-1Ky">
<rect key="frame" x="1" y="8" width="100" height="17"/>
<rect key="frame" x="1" y="9" width="100" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="fcm-Ye-Lfm">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -96,20 +96,20 @@
</tableHeaderView>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="plE-qX-bpe">
<rect key="frame" x="-2" y="399" width="34" height="14"/>
<rect key="frame" x="-2" y="351" width="34" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Delay" id="cXS-Pi-ivX">
<font key="font" metaFont="smallSystem"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oUC-sz-rhD">
<rect key="frame" x="38" y="396" width="47" height="19"/>
<rect key="frame" x="38" y="349" width="47" height="19"/>
<constraints>
<constraint firstAttribute="width" constant="47" id="nlk-Br-93E"/>
</constraints>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" continuous="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="BXa-cB-6Un">
<font key="font" metaFont="smallSystem"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -118,32 +118,32 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QuO-mJ-lxJ">
<rect key="frame" x="93" y="399" width="50" height="14"/>
<rect key="frame" x="93" y="351" width="50" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Seconds" id="Wzj-aB-RWy">
<font key="font" metaFont="smallSystem"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="AYd-xZ-eWR">
<rect key="frame" x="0.0" y="205" width="250" height="183"/>
<rect key="frame" x="0.0" y="158" width="250" height="183"/>
</customView>
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UIM-Jo-xaV">
<rect key="frame" x="0.0" y="40" width="250" height="135"/>
<clipView key="contentView" id="ro4-J8-STr">
<rect key="frame" x="1" y="1" width="248" height="133"/>
<rect key="frame" x="0.0" y="40" width="250" height="88"/>
<clipView key="contentView" ambiguous="YES" id="ro4-J8-STr">
<rect key="frame" x="1" y="1" width="248" height="86"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="LGa-Si-5th">
<rect key="frame" x="0.0" y="0.0" width="248" height="133"/>
<autoresizingMask key="autoresizingMask"/>
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="LGa-Si-5th">
<rect key="frame" x="0.0" y="0.0" width="248" height="86"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="245" minWidth="40" maxWidth="1000" id="UQh-t7-CIi">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -159,7 +159,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="qCS-zv-h2M">
<rect key="frame" x="0.0" y="0.0" width="245" height="17"/>
<rect key="frame" x="0.0" y="1" width="245" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="wiU-GO-hdY">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -186,8 +186,8 @@
</tableColumn>
</tableColumns>
<connections>
<binding destination="OYm-wd-HNd" name="content" keyPath="arrangedObjects.value" id="zXO-hB-uea"/>
<binding destination="OYm-wd-HNd" name="selectionIndexes" keyPath="selectionIndexes" previousBinding="zXO-hB-uea" id="ekn-Li-u3w"/>
<binding destination="OYm-wd-HNd" name="content" keyPath="arrangedObjects.value.outputTrack" id="Agi-WO-WSY"/>
<binding destination="OYm-wd-HNd" name="selectionIndexes" keyPath="selectionIndexes" previousBinding="Agi-WO-WSY" id="bW3-Jn-Gpl"/>
</connections>
</tableView>
</subviews>
@ -202,28 +202,28 @@
</scroller>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Cvv-QQ-fxp">
<rect key="frame" x="-2" y="183" width="72" height="14"/>
<rect key="frame" x="-2" y="136" width="72" height="14"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Audio Tracks" id="Qcq-zU-WR1">
<font key="font" metaFont="smallSystem"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="p6z-a7-eCZ">
<rect key="frame" x="1" y="20" width="20" height="22"/>
<button verticalHuggingPriority="750" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="p6z-a7-eCZ">
<rect key="frame" x="1" y="-3" width="20" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="h40-UI-Q7O"/>
<constraint firstAttribute="height" constant="20" id="xC3-Cc-62f"/>
</constraints>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSAddTemplate" imagePosition="overlaps" alignment="center" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3FI-Yo-gB1">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystem"/>
<font key="font" metaFont="controlContent" size="11"/>
</buttonCell>
<connections>
<action selector="trackAddClicked:" target="-2" id="m4h-Ho-rYk"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="znN-Sl-DdI">
<button verticalHuggingPriority="750" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="znN-Sl-DdI">
<rect key="frame" x="21" y="20" width="20" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="Zri-iC-0c0"/>
@ -231,7 +231,7 @@
</constraints>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSRemoveTemplate" imagePosition="overlaps" alignment="center" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="9lR-Ma-HYn">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystem"/>
<font key="font" metaFont="controlContent" size="11"/>
</buttonCell>
<connections>
<action selector="trackRemoveClicked:" target="-2" id="yEW-F4-dHc"/>