Skip to content

Commit

Permalink
Working demo 20150322
Browse files Browse the repository at this point in the history
  • Loading branch information
robotlovesyou committed Mar 22, 2015
1 parent 1e38c47 commit 70b0a5d
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
/Audio\ Mixer\ Demo.xcodeproj/xcuserdata/
6 changes: 6 additions & 0 deletions Audio Mixer Demo.xcodeproj/project.pbxproj
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
A16E9B6F1ABF395F00C6081A /* farah-faucet.wav in Resources */ = {isa = PBXBuildFile; fileRef = A16E9B6E1ABF395F00C6081A /* farah-faucet.wav */; };
A1EA8BA81AB393A20055155E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1EA8BA71AB393A20055155E /* AppDelegate.swift */; };
A1EA8BAA1AB393A20055155E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1EA8BA91AB393A20055155E /* ViewController.swift */; };
A1EA8BAD1AB393A20055155E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1EA8BAB1AB393A20055155E /* Main.storyboard */; };
Expand All @@ -26,6 +27,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
A16E9B6E1ABF395F00C6081A /* farah-faucet.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = "farah-faucet.wav"; sourceTree = "<group>"; };
A1EA8BA21AB393A20055155E /* Audio Mixer Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Audio Mixer Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
A1EA8BA61AB393A20055155E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A1EA8BA71AB393A20055155E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -90,6 +92,7 @@
A1EA8BA51AB393A20055155E /* Supporting Files */ = {
isa = PBXGroup;
children = (
A16E9B6E1ABF395F00C6081A /* farah-faucet.wav */,
A1EA8BA61AB393A20055155E /* Info.plist */,
);
name = "Supporting Files";
Expand Down Expand Up @@ -195,6 +198,7 @@
A1EA8BAD1AB393A20055155E /* Main.storyboard in Resources */,
A1EA8BB21AB393A20055155E /* LaunchScreen.xib in Resources */,
A1EA8BAF1AB393A20055155E /* Images.xcassets in Resources */,
A16E9B6F1ABF395F00C6081A /* farah-faucet.wav in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -405,6 +409,7 @@
A1EA8BC31AB393A20055155E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
A1EA8BC41AB393A20055155E /* Build configuration list for PBXNativeTarget "Audio Mixer DemoTests" */ = {
isa = XCConfigurationList;
Expand All @@ -413,6 +418,7 @@
A1EA8BC61AB393A20055155E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
Expand Down
79 changes: 76 additions & 3 deletions Audio Mixer Demo/Base.lproj/Main.storyboard
@@ -1,22 +1,95 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1510" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="ufC-wZ-h7g">
<objects>
<viewController id="vXZ-lx-hvc" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
<viewController id="vXZ-lx-hvc" customClass="ViewController" customModule="Audio_Mixer_Demo" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2si-Xz-fdv">
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
<state key="normal" title="Play">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="playButtonTapped:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="lbe-VW-bdH"/>
</connections>
</button>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="pp1-t7-AbO">
<rect key="frame" x="0.0" y="-15" width="118" height="31"/>
<connections>
<action selector="sliderChanged:" destination="vXZ-lx-hvc" eventType="valueChanged" id="Hvf-Ge-TuE"/>
</connections>
</slider>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ym2-wr-urn">
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
<state key="normal" title="Pause">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="pauseButtonTapped:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="Yij-kl-JBG"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="2si-Xz-fdv" firstAttribute="top" secondItem="jyV-Pf-zRb" secondAttribute="bottom" constant="44" id="4j0-XI-igb"/>
<constraint firstAttribute="centerX" secondItem="ym2-wr-urn" secondAttribute="centerX" constant="7.5" id="IbA-ZV-9Jt"/>
<constraint firstAttribute="centerX" secondItem="2si-Xz-fdv" secondAttribute="centerX" constant="8" id="MbE-BU-6cq"/>
<constraint firstItem="pp1-t7-AbO" firstAttribute="top" secondItem="2si-Xz-fdv" secondAttribute="bottom" constant="44" id="Y7H-e4-rFh"/>
<constraint firstItem="ym2-wr-urn" firstAttribute="top" secondItem="pp1-t7-AbO" secondAttribute="bottom" constant="44" id="hKQ-zp-8d6"/>
<constraint firstItem="pp1-t7-AbO" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" constant="20" id="n24-Uk-MkJ"/>
<constraint firstAttribute="centerX" secondItem="pp1-t7-AbO" secondAttribute="centerX" constant="8" id="npu-iH-NwZ"/>
</constraints>
<variation key="default">
<mask key="subviews">
<exclude reference="2si-Xz-fdv"/>
<exclude reference="pp1-t7-AbO"/>
<exclude reference="ym2-wr-urn"/>
</mask>
<mask key="constraints">
<exclude reference="Y7H-e4-rFh"/>
<exclude reference="n24-Uk-MkJ"/>
<exclude reference="npu-iH-NwZ"/>
<exclude reference="4j0-XI-igb"/>
<exclude reference="MbE-BU-6cq"/>
<exclude reference="IbA-ZV-9Jt"/>
<exclude reference="hKQ-zp-8d6"/>
</mask>
</variation>
<variation key="heightClass=regular-widthClass=compact">
<mask key="subviews">
<include reference="2si-Xz-fdv"/>
<include reference="pp1-t7-AbO"/>
<include reference="ym2-wr-urn"/>
</mask>
<mask key="constraints">
<include reference="Y7H-e4-rFh"/>
<include reference="n24-Uk-MkJ"/>
<include reference="npu-iH-NwZ"/>
<include reference="4j0-XI-igb"/>
<include reference="MbE-BU-6cq"/>
<include reference="IbA-ZV-9Jt"/>
<include reference="hKQ-zp-8d6"/>
</mask>
</variation>
</view>
<connections>
<outlet property="pauseButton" destination="ym2-wr-urn" id="N7y-T7-P46"/>
<outlet property="playButton" destination="2si-Xz-fdv" id="ziP-Fg-oiW"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
Expand Down
2 changes: 0 additions & 2 deletions Audio Mixer Demo/Info.plist
Expand Up @@ -33,8 +33,6 @@
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
86 changes: 86 additions & 0 deletions Audio Mixer Demo/ViewController.swift
Expand Up @@ -7,19 +7,105 @@
//

import UIKit
import AVFoundation

class ViewController: UIViewController {

@IBOutlet weak var playButton: UIButton!
@IBOutlet weak var pauseButton: UIButton!
var engine: AVAudioEngine!
var playerA: AVAudioPlayerNode!
var playerB: AVAudioPlayerNode!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
engine = AVAudioEngine()
playerA = AVAudioPlayerNode()
playerB = AVAudioPlayerNode()
playerA.volume = 0.5
playerB.volume = 0.5

// Tsk tsk, automatically unwrapping optionals is bad form, but
// this is just a demo so I'll let you off.
// Here you are getting the path for the sound file you added to your project and converting it into a file url.
let path = NSBundle.mainBundle().pathForResource("farah-faucet", ofType: "wav")!
let url = NSURL.fileURLWithPath(path)!

// Here you are creating an AVAudioFile from the sound file,
// preparing a buffer of the correct format and length and loading
// the file into the buffer.
var file = AVAudioFile(forReading: url, error: nil)
var buffer = AVAudioPCMBuffer(PCMFormat: file.processingFormat, frameCapacity: AVAudioFrameCount(file.length))
file.readIntoBuffer(buffer, error: nil)

// This is a reverb with a cathedral preset. It's nice and ethereal
// You're also setting the wetDryMix which controls the mix between the effect and the
// original sound.
var reverb = AVAudioUnitReverb()
reverb.loadFactoryPreset(AVAudioUnitReverbPreset.Cathedral)
reverb.wetDryMix = 50

// This is a distortion with a radio tower preset which works well for speech
// As distortion tends to be quite loud you're setting the wetDryMix to only 25
var distortion = AVAudioUnitDistortion()
distortion.loadFactoryPreset(AVAudioUnitDistortionPreset.SpeechRadioTower)
distortion.wetDryMix = 25

// Attach the four nodes to the audio engine
engine.attachNode(playerA)
engine.attachNode(playerB)
engine.attachNode(reverb)
engine.attachNode(distortion)

// Connect playerA to the reverb
engine.connect(playerA, to: reverb, format: buffer.format)

// Connect the reverb to the mixer
engine.connect(reverb, to: engine.mainMixerNode, format: buffer.format)

// Connect playerB to the distortion
engine.connect(playerB, to: distortion, format: buffer.format)

// Connect the distortion to the mixer
engine.connect(distortion, to: engine.mainMixerNode, format: buffer.format)

// Schedule playerA and playerB to play the buffer on a loop
playerA.scheduleBuffer(buffer, atTime: nil, options: AVAudioPlayerNodeBufferOptions.Loops, completionHandler: nil)
playerB.scheduleBuffer(buffer, atTime: nil, options: AVAudioPlayerNodeBufferOptions.Loops, completionHandler: nil)

// Start the audio engine
engine.prepare()
engine.startAndReturnError(nil)

}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

func togglePlayPauseHidden() {
pauseButton.hidden = !pauseButton.hidden
playButton.hidden = !playButton.hidden
}

@IBAction func playButtonTapped(sender: UIButton) {
playerA.play()
playerB.play()
togglePlayPauseHidden()
}

@IBAction func pauseButtonTapped(sender: UIButton) {
playerA.pause()
playerB.pause()
togglePlayPauseHidden()
}

@IBAction func sliderChanged(sender: UISlider) {
playerA.volume = sender.value
playerB.volume = 1.0 - sender.value
}

}

Binary file added Audio Mixer Demo/farah-faucet.wav
Binary file not shown.

0 comments on commit 70b0a5d

Please sign in to comment.