├── .DS_Store
├── .gitignore
├── AudioUnitSample
├── .DS_Store
├── AudioUnitSample.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── MixPlaying
│ ├── .DS_Store
│ ├── MixPlaying.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── MixPlaying
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── SKAudioBuffer.h
│ │ ├── SKAudioBuffer.m
│ │ ├── SKAudioConverter.h
│ │ ├── SKAudioConverter.m
│ │ ├── SKAudioParser.h
│ │ ├── SKAudioParser.m
│ │ ├── ViewController.h
│ │ ├── ViewController.m
│ │ └── main.m
├── RemoteInput
│ ├── .DS_Store
│ ├── RemoteInput.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── RemoteInput
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── SKAudioBuffer.h
│ │ ├── SKAudioBuffer.m
│ │ ├── SKAudioConverter.h
│ │ ├── SKAudioConverter.m
│ │ ├── SKAudioParser.h
│ │ ├── SKAudioParser.m
│ │ ├── ViewController.h
│ │ ├── ViewController.m
│ │ └── main.m
└── SimplePlaying
│ ├── .DS_Store
│ ├── SimplePlaying.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── SimplePlaying
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ ├── SKAudioBuffer.h
│ ├── SKAudioBuffer.m
│ ├── SKAudioConverter.h
│ ├── SKAudioConverter.m
│ ├── SKAudioParser.h
│ ├── SKAudioParser.m
│ ├── ViewController.h
│ ├── ViewController.m
│ └── main.m
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevenKuo/AudioUnitSample/b50c8111600d283cbde02ce48f1ae36b3aa49f61/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # CocoaPods
21 | #
22 | # We recommend against adding the Pods directory to your .gitignore. However
23 | # you should judge for yourself, the pros and cons are mentioned at:
24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
25 | #
26 | #Pods/
27 |
--------------------------------------------------------------------------------
/AudioUnitSample/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevenKuo/AudioUnitSample/b50c8111600d283cbde02ce48f1ae36b3aa49f61/AudioUnitSample/.DS_Store
--------------------------------------------------------------------------------
/AudioUnitSample/AudioUnitSample.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/AudioUnitSample/AudioUnitSample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevenKuo/AudioUnitSample/b50c8111600d283cbde02ce48f1ae36b3aa49f61/AudioUnitSample/MixPlaying/.DS_Store
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9CCFA5A21BFDDFF400981DA9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CCFA5A11BFDDFF400981DA9 /* main.m */; };
11 | 9CCFA5A51BFDDFF400981DA9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CCFA5A41BFDDFF400981DA9 /* AppDelegate.m */; };
12 | 9CCFA5A81BFDDFF400981DA9 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CCFA5A71BFDDFF400981DA9 /* ViewController.m */; };
13 | 9CCFA5AB1BFDDFF400981DA9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9CCFA5A91BFDDFF400981DA9 /* Main.storyboard */; };
14 | 9CCFA5AD1BFDDFF400981DA9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9CCFA5AC1BFDDFF400981DA9 /* Assets.xcassets */; };
15 | 9CCFA5B01BFDDFF400981DA9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9CCFA5AE1BFDDFF400981DA9 /* LaunchScreen.storyboard */; };
16 | 9CCFA5BD1BFDE01700981DA9 /* SKAudioBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CCFA5B81BFDE01700981DA9 /* SKAudioBuffer.m */; };
17 | 9CCFA5BE1BFDE01700981DA9 /* SKAudioConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CCFA5BA1BFDE01700981DA9 /* SKAudioConverter.m */; };
18 | 9CCFA5BF1BFDE01700981DA9 /* SKAudioParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CCFA5BC1BFDE01700981DA9 /* SKAudioParser.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | 9CCFA59D1BFDDFF400981DA9 /* MixPlaying.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MixPlaying.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | 9CCFA5A11BFDDFF400981DA9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
24 | 9CCFA5A31BFDDFF400981DA9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
25 | 9CCFA5A41BFDDFF400981DA9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
26 | 9CCFA5A61BFDDFF400981DA9 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
27 | 9CCFA5A71BFDDFF400981DA9 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
28 | 9CCFA5AA1BFDDFF400981DA9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
29 | 9CCFA5AC1BFDDFF400981DA9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
30 | 9CCFA5AF1BFDDFF400981DA9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
31 | 9CCFA5B11BFDDFF400981DA9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
32 | 9CCFA5B71BFDE01700981DA9 /* SKAudioBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKAudioBuffer.h; sourceTree = ""; };
33 | 9CCFA5B81BFDE01700981DA9 /* SKAudioBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKAudioBuffer.m; sourceTree = ""; };
34 | 9CCFA5B91BFDE01700981DA9 /* SKAudioConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKAudioConverter.h; sourceTree = ""; };
35 | 9CCFA5BA1BFDE01700981DA9 /* SKAudioConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKAudioConverter.m; sourceTree = ""; };
36 | 9CCFA5BB1BFDE01700981DA9 /* SKAudioParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKAudioParser.h; sourceTree = ""; };
37 | 9CCFA5BC1BFDE01700981DA9 /* SKAudioParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKAudioParser.m; sourceTree = ""; };
38 | /* End PBXFileReference section */
39 |
40 | /* Begin PBXFrameworksBuildPhase section */
41 | 9CCFA59A1BFDDFF400981DA9 /* Frameworks */ = {
42 | isa = PBXFrameworksBuildPhase;
43 | buildActionMask = 2147483647;
44 | files = (
45 | );
46 | runOnlyForDeploymentPostprocessing = 0;
47 | };
48 | /* End PBXFrameworksBuildPhase section */
49 |
50 | /* Begin PBXGroup section */
51 | 9CCFA5941BFDDFF400981DA9 = {
52 | isa = PBXGroup;
53 | children = (
54 | 9CCFA59F1BFDDFF400981DA9 /* MixPlaying */,
55 | 9CCFA59E1BFDDFF400981DA9 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | 9CCFA59E1BFDDFF400981DA9 /* Products */ = {
60 | isa = PBXGroup;
61 | children = (
62 | 9CCFA59D1BFDDFF400981DA9 /* MixPlaying.app */,
63 | );
64 | name = Products;
65 | sourceTree = "";
66 | };
67 | 9CCFA59F1BFDDFF400981DA9 /* MixPlaying */ = {
68 | isa = PBXGroup;
69 | children = (
70 | 9CCFA5B71BFDE01700981DA9 /* SKAudioBuffer.h */,
71 | 9CCFA5B81BFDE01700981DA9 /* SKAudioBuffer.m */,
72 | 9CCFA5B91BFDE01700981DA9 /* SKAudioConverter.h */,
73 | 9CCFA5BA1BFDE01700981DA9 /* SKAudioConverter.m */,
74 | 9CCFA5BB1BFDE01700981DA9 /* SKAudioParser.h */,
75 | 9CCFA5BC1BFDE01700981DA9 /* SKAudioParser.m */,
76 | 9CCFA5A31BFDDFF400981DA9 /* AppDelegate.h */,
77 | 9CCFA5A41BFDDFF400981DA9 /* AppDelegate.m */,
78 | 9CCFA5A61BFDDFF400981DA9 /* ViewController.h */,
79 | 9CCFA5A71BFDDFF400981DA9 /* ViewController.m */,
80 | 9CCFA5A91BFDDFF400981DA9 /* Main.storyboard */,
81 | 9CCFA5AC1BFDDFF400981DA9 /* Assets.xcassets */,
82 | 9CCFA5AE1BFDDFF400981DA9 /* LaunchScreen.storyboard */,
83 | 9CCFA5B11BFDDFF400981DA9 /* Info.plist */,
84 | 9CCFA5A01BFDDFF400981DA9 /* Supporting Files */,
85 | );
86 | path = MixPlaying;
87 | sourceTree = "";
88 | };
89 | 9CCFA5A01BFDDFF400981DA9 /* Supporting Files */ = {
90 | isa = PBXGroup;
91 | children = (
92 | 9CCFA5A11BFDDFF400981DA9 /* main.m */,
93 | );
94 | name = "Supporting Files";
95 | sourceTree = "";
96 | };
97 | /* End PBXGroup section */
98 |
99 | /* Begin PBXNativeTarget section */
100 | 9CCFA59C1BFDDFF400981DA9 /* MixPlaying */ = {
101 | isa = PBXNativeTarget;
102 | buildConfigurationList = 9CCFA5B41BFDDFF400981DA9 /* Build configuration list for PBXNativeTarget "MixPlaying" */;
103 | buildPhases = (
104 | 9CCFA5991BFDDFF400981DA9 /* Sources */,
105 | 9CCFA59A1BFDDFF400981DA9 /* Frameworks */,
106 | 9CCFA59B1BFDDFF400981DA9 /* Resources */,
107 | );
108 | buildRules = (
109 | );
110 | dependencies = (
111 | );
112 | name = MixPlaying;
113 | productName = MixPlaying;
114 | productReference = 9CCFA59D1BFDDFF400981DA9 /* MixPlaying.app */;
115 | productType = "com.apple.product-type.application";
116 | };
117 | /* End PBXNativeTarget section */
118 |
119 | /* Begin PBXProject section */
120 | 9CCFA5951BFDDFF400981DA9 /* Project object */ = {
121 | isa = PBXProject;
122 | attributes = {
123 | LastUpgradeCheck = 0710;
124 | ORGANIZATIONNAME = StevenKuo;
125 | TargetAttributes = {
126 | 9CCFA59C1BFDDFF400981DA9 = {
127 | CreatedOnToolsVersion = 7.1.1;
128 | };
129 | };
130 | };
131 | buildConfigurationList = 9CCFA5981BFDDFF400981DA9 /* Build configuration list for PBXProject "MixPlaying" */;
132 | compatibilityVersion = "Xcode 3.2";
133 | developmentRegion = English;
134 | hasScannedForEncodings = 0;
135 | knownRegions = (
136 | en,
137 | Base,
138 | );
139 | mainGroup = 9CCFA5941BFDDFF400981DA9;
140 | productRefGroup = 9CCFA59E1BFDDFF400981DA9 /* Products */;
141 | projectDirPath = "";
142 | projectRoot = "";
143 | targets = (
144 | 9CCFA59C1BFDDFF400981DA9 /* MixPlaying */,
145 | );
146 | };
147 | /* End PBXProject section */
148 |
149 | /* Begin PBXResourcesBuildPhase section */
150 | 9CCFA59B1BFDDFF400981DA9 /* Resources */ = {
151 | isa = PBXResourcesBuildPhase;
152 | buildActionMask = 2147483647;
153 | files = (
154 | 9CCFA5B01BFDDFF400981DA9 /* LaunchScreen.storyboard in Resources */,
155 | 9CCFA5AD1BFDDFF400981DA9 /* Assets.xcassets in Resources */,
156 | 9CCFA5AB1BFDDFF400981DA9 /* Main.storyboard in Resources */,
157 | );
158 | runOnlyForDeploymentPostprocessing = 0;
159 | };
160 | /* End PBXResourcesBuildPhase section */
161 |
162 | /* Begin PBXSourcesBuildPhase section */
163 | 9CCFA5991BFDDFF400981DA9 /* Sources */ = {
164 | isa = PBXSourcesBuildPhase;
165 | buildActionMask = 2147483647;
166 | files = (
167 | 9CCFA5BE1BFDE01700981DA9 /* SKAudioConverter.m in Sources */,
168 | 9CCFA5BD1BFDE01700981DA9 /* SKAudioBuffer.m in Sources */,
169 | 9CCFA5A81BFDDFF400981DA9 /* ViewController.m in Sources */,
170 | 9CCFA5BF1BFDE01700981DA9 /* SKAudioParser.m in Sources */,
171 | 9CCFA5A51BFDDFF400981DA9 /* AppDelegate.m in Sources */,
172 | 9CCFA5A21BFDDFF400981DA9 /* main.m in Sources */,
173 | );
174 | runOnlyForDeploymentPostprocessing = 0;
175 | };
176 | /* End PBXSourcesBuildPhase section */
177 |
178 | /* Begin PBXVariantGroup section */
179 | 9CCFA5A91BFDDFF400981DA9 /* Main.storyboard */ = {
180 | isa = PBXVariantGroup;
181 | children = (
182 | 9CCFA5AA1BFDDFF400981DA9 /* Base */,
183 | );
184 | name = Main.storyboard;
185 | sourceTree = "";
186 | };
187 | 9CCFA5AE1BFDDFF400981DA9 /* LaunchScreen.storyboard */ = {
188 | isa = PBXVariantGroup;
189 | children = (
190 | 9CCFA5AF1BFDDFF400981DA9 /* Base */,
191 | );
192 | name = LaunchScreen.storyboard;
193 | sourceTree = "";
194 | };
195 | /* End PBXVariantGroup section */
196 |
197 | /* Begin XCBuildConfiguration section */
198 | 9CCFA5B21BFDDFF400981DA9 /* Debug */ = {
199 | isa = XCBuildConfiguration;
200 | buildSettings = {
201 | ALWAYS_SEARCH_USER_PATHS = NO;
202 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
203 | CLANG_CXX_LIBRARY = "libc++";
204 | CLANG_ENABLE_MODULES = YES;
205 | CLANG_ENABLE_OBJC_ARC = YES;
206 | CLANG_WARN_BOOL_CONVERSION = YES;
207 | CLANG_WARN_CONSTANT_CONVERSION = YES;
208 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
209 | CLANG_WARN_EMPTY_BODY = YES;
210 | CLANG_WARN_ENUM_CONVERSION = YES;
211 | CLANG_WARN_INT_CONVERSION = YES;
212 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
213 | CLANG_WARN_UNREACHABLE_CODE = YES;
214 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
215 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
216 | COPY_PHASE_STRIP = NO;
217 | DEBUG_INFORMATION_FORMAT = dwarf;
218 | ENABLE_STRICT_OBJC_MSGSEND = YES;
219 | ENABLE_TESTABILITY = YES;
220 | GCC_C_LANGUAGE_STANDARD = gnu99;
221 | GCC_DYNAMIC_NO_PIC = NO;
222 | GCC_NO_COMMON_BLOCKS = YES;
223 | GCC_OPTIMIZATION_LEVEL = 0;
224 | GCC_PREPROCESSOR_DEFINITIONS = (
225 | "DEBUG=1",
226 | "$(inherited)",
227 | );
228 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
229 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
230 | GCC_WARN_UNDECLARED_SELECTOR = YES;
231 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
232 | GCC_WARN_UNUSED_FUNCTION = YES;
233 | GCC_WARN_UNUSED_VARIABLE = YES;
234 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
235 | MTL_ENABLE_DEBUG_INFO = YES;
236 | ONLY_ACTIVE_ARCH = YES;
237 | SDKROOT = iphoneos;
238 | TARGETED_DEVICE_FAMILY = "1,2";
239 | };
240 | name = Debug;
241 | };
242 | 9CCFA5B31BFDDFF400981DA9 /* Release */ = {
243 | isa = XCBuildConfiguration;
244 | buildSettings = {
245 | ALWAYS_SEARCH_USER_PATHS = NO;
246 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
247 | CLANG_CXX_LIBRARY = "libc++";
248 | CLANG_ENABLE_MODULES = YES;
249 | CLANG_ENABLE_OBJC_ARC = YES;
250 | CLANG_WARN_BOOL_CONVERSION = YES;
251 | CLANG_WARN_CONSTANT_CONVERSION = YES;
252 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
253 | CLANG_WARN_EMPTY_BODY = YES;
254 | CLANG_WARN_ENUM_CONVERSION = YES;
255 | CLANG_WARN_INT_CONVERSION = YES;
256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 | CLANG_WARN_UNREACHABLE_CODE = YES;
258 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
259 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
260 | COPY_PHASE_STRIP = NO;
261 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
262 | ENABLE_NS_ASSERTIONS = NO;
263 | ENABLE_STRICT_OBJC_MSGSEND = YES;
264 | GCC_C_LANGUAGE_STANDARD = gnu99;
265 | GCC_NO_COMMON_BLOCKS = YES;
266 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
267 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
268 | GCC_WARN_UNDECLARED_SELECTOR = YES;
269 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
270 | GCC_WARN_UNUSED_FUNCTION = YES;
271 | GCC_WARN_UNUSED_VARIABLE = YES;
272 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
273 | MTL_ENABLE_DEBUG_INFO = NO;
274 | SDKROOT = iphoneos;
275 | TARGETED_DEVICE_FAMILY = "1,2";
276 | VALIDATE_PRODUCT = YES;
277 | };
278 | name = Release;
279 | };
280 | 9CCFA5B51BFDDFF400981DA9 /* Debug */ = {
281 | isa = XCBuildConfiguration;
282 | buildSettings = {
283 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
284 | INFOPLIST_FILE = MixPlaying/Info.plist;
285 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
286 | PRODUCT_BUNDLE_IDENTIFIER = SK.MixPlaying;
287 | PRODUCT_NAME = "$(TARGET_NAME)";
288 | };
289 | name = Debug;
290 | };
291 | 9CCFA5B61BFDDFF400981DA9 /* Release */ = {
292 | isa = XCBuildConfiguration;
293 | buildSettings = {
294 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
295 | INFOPLIST_FILE = MixPlaying/Info.plist;
296 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
297 | PRODUCT_BUNDLE_IDENTIFIER = SK.MixPlaying;
298 | PRODUCT_NAME = "$(TARGET_NAME)";
299 | };
300 | name = Release;
301 | };
302 | /* End XCBuildConfiguration section */
303 |
304 | /* Begin XCConfigurationList section */
305 | 9CCFA5981BFDDFF400981DA9 /* Build configuration list for PBXProject "MixPlaying" */ = {
306 | isa = XCConfigurationList;
307 | buildConfigurations = (
308 | 9CCFA5B21BFDDFF400981DA9 /* Debug */,
309 | 9CCFA5B31BFDDFF400981DA9 /* Release */,
310 | );
311 | defaultConfigurationIsVisible = 0;
312 | defaultConfigurationName = Release;
313 | };
314 | 9CCFA5B41BFDDFF400981DA9 /* Build configuration list for PBXNativeTarget "MixPlaying" */ = {
315 | isa = XCConfigurationList;
316 | buildConfigurations = (
317 | 9CCFA5B51BFDDFF400981DA9 /* Debug */,
318 | 9CCFA5B61BFDDFF400981DA9 /* Release */,
319 | );
320 | defaultConfigurationIsVisible = 0;
321 | };
322 | /* End XCConfigurationList section */
323 | };
324 | rootObject = 9CCFA5951BFDDFF400981DA9 /* Project object */;
325 | }
326 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // MixPlaying
4 | //
5 | // Created by StevenKuo on 2015/11/19.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // MixPlaying
4 | //
5 | // Created by StevenKuo on 2015/11/19.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
49 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/SKAudioBuffer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioBuffer.h
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | typedef struct {
13 | AudioStreamPacketDescription packetDescription;
14 | void *data;
15 | } AudioPacketInfo;
16 |
17 | @class SKAudioBuffer;
18 |
19 | @protocol SKAudioBufferDelegate
20 |
21 | - (AudioStreamBasicDescription)usedAudioStreamBasicDescription;
22 | - (void)audioBufferDidBeginReadPacket:(SKAudioBuffer *)inBuffer;
23 | @end
24 |
25 | @interface SKAudioBuffer : NSObject
26 | {
27 | __weak id delegate;
28 |
29 | AudioPacketInfo *packets;
30 | size_t packetWriteIndex;
31 | size_t packetReadIndex;
32 | size_t packetCount;
33 |
34 | NSMutableData *audioData;
35 | NSMutableData *packetDescData;
36 | NSUInteger packetReadHead;
37 | NSUInteger readPacketIndex;
38 | }
39 |
40 |
41 | - (void)storePacketData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount;
42 | - (void)movePacketReadIndex;
43 |
44 | @property (readonly, nonatomic) size_t availablePacketCount;
45 | @property (weak, nonatomic) id delegate;
46 | @property (readonly, nonatomic) AudioPacketInfo currentPacketInfo;
47 | @end
48 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/SKAudioBuffer.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioBuffer.m
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import "SKAudioBuffer.h"
10 |
11 | @implementation SKAudioBuffer
12 |
13 | - (id)init
14 | {
15 | self = [super init];
16 | if (self) {
17 |
18 | packetCount = 2048;
19 | packets = (AudioPacketInfo *)calloc(packetCount, sizeof(AudioPacketInfo));
20 |
21 | audioData = [[NSMutableData alloc] init];
22 | packetDescData = [[NSMutableData alloc] init];
23 | }
24 | return self;
25 | }
26 |
27 |
28 | - (void)storePacketData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount
29 | {
30 | // for (NSUInteger packetIndex = 0; packetIndex < inPacketsCount ; packetIndex ++) {
31 | // inPacketDescriptions[packetIndex].mStartOffset += audioData.length;
32 | // }
33 | //
34 | // @synchronized (self) {
35 | // [audioData appendBytes:inBytes length:inLength];
36 | // [packetDescData appendBytes:inPacketDescriptions length:sizeof(AudioStreamPacketDescription) * inPacketsCount];
37 | // availablePacketCount += inPacketsCount;
38 | // }
39 |
40 | @synchronized (self) {
41 |
42 | for (size_t index = 0; index < inPacketsCount; index ++) {
43 |
44 | if (packetWriteIndex >= packetCount) {
45 | size_t oldSize = packetCount * sizeof(AudioPacketInfo);
46 | packetCount = packetCount * 2;
47 | packets = (AudioPacketInfo *)realloc(packets, packetCount * sizeof(AudioPacketInfo));
48 | bzero((void *)packets + oldSize, oldSize);
49 | }
50 | AudioStreamPacketDescription emptyDescription;
51 |
52 | if (!inPacketDescriptions) {
53 | emptyDescription.mStartOffset = index;
54 | emptyDescription.mDataByteSize = 1;
55 | emptyDescription.mVariableFramesInPacket = 0;
56 | }
57 |
58 | AudioStreamPacketDescription *currentDescription = inPacketDescriptions ? &(inPacketDescriptions[index]) : &emptyDescription;
59 |
60 | AudioPacketInfo *nextInfo = &packets[packetWriteIndex];
61 | if (nextInfo->data) {
62 | free(nextInfo->data);
63 | nextInfo->data = NULL;
64 | }
65 | nextInfo->data = malloc(currentDescription->mDataByteSize);
66 | NSAssert(nextInfo->data, @"Must allocate memory for current packet");
67 | memcpy(nextInfo->data, inBytes + currentDescription->mStartOffset, currentDescription->mDataByteSize);
68 | memcpy(&nextInfo->packetDescription, currentDescription, sizeof(AudioStreamPacketDescription));
69 |
70 | packetWriteIndex++;
71 |
72 | _availablePacketCount++;
73 | }
74 | }
75 | }
76 |
77 | - (void)setPacketReadIndex:(size_t)inNewIndex
78 | {
79 | size_t max = _availablePacketCount;
80 |
81 | if (inNewIndex > max) {
82 | packetReadIndex = max;
83 | return;
84 | }
85 |
86 | if (inNewIndex < packetWriteIndex) {
87 | packetReadIndex = inNewIndex;
88 | }
89 | else {
90 | packetReadIndex = packetWriteIndex;
91 | }
92 | }
93 |
94 | - (void)movePacketReadIndex
95 | {
96 | [self setPacketReadIndex:packetReadIndex + 1];
97 | }
98 |
99 | - (AudioPacketInfo)currentPacketInfo
100 | {
101 | // @synchronized (self) {
102 | // if (readPacketIndex >= availablePacketCount) {
103 | // inCallback(nil, 0, nil, YES);
104 | // return;
105 | // }
106 | // if (readPacketIndex == 0) {
107 | // [delegate audioBufferDidBeginReadPacket:self];
108 | // }
109 | //
110 | // AudioStreamPacketDescription* packetDescriptions = (AudioStreamPacketDescription* )packetDescData.bytes;
111 | //
112 | // AudioPacketInfo *packet = (AudioPacketInfo *)calloc(1, sizeof(AudioPacketInfo));
113 | // packet->data = malloc(packetDescriptions[readPacketIndex].mDataByteSize);
114 | // memcpy(packet->data, audioData.bytes + packetDescriptions[readPacketIndex].mStartOffset, packetDescriptions[readPacketIndex].mDataByteSize);
115 | // memcpy(&packet->packetDescription, &packetDescriptions[readPacketIndex], sizeof(AudioStreamPacketDescription));
116 | //
117 | // readPacketIndex ++;
118 | //
119 | // return *packet;
120 | // }
121 | return packets[packetReadIndex];
122 | }
123 |
124 | @synthesize delegate;
125 | @synthesize currentPacketInfo;
126 | @end
127 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/SKAudioConverter.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioConverter.h
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "SKAudioBuffer.h"
12 |
13 | @interface SKAudioConverter : NSObject
14 | {
15 | AudioStreamBasicDescription audioStreamDescription;
16 | AudioStreamBasicDescription destFormat;
17 | AudioConverterRef converter;
18 | AudioBufferList *renderBufferList;
19 | UInt32 renderBufferSize;
20 | }
21 |
22 | AudioStreamBasicDescription LinearPCMStreamDescription();
23 |
24 | - (instancetype)initWithSourceFormat:(AudioStreamBasicDescription *)sourceFormat;
25 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber buffer:(SKAudioBuffer *)inBuffer;
26 |
27 | - (void)_fillBufferlist:(AudioBufferList *)ioData withBuffer:(SKAudioBuffer *)buffer packetDescription:(AudioStreamPacketDescription** )outDataPacketDescription;
28 | @property (readonly, nonatomic) double packetsPerSecond;
29 | @end
30 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/SKAudioConverter.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioConverter.m
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "SKAudioConverter.h"
10 |
11 | static OSStatus AudioConverterFiller(AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData);
12 |
13 | OSStatus AudioConverterFiller (AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData)
14 | {
15 | NSArray *args = (__bridge NSArray *)inUserData;
16 | SKAudioConverter *self = args[0];
17 | SKAudioBuffer *buffer = args[1];
18 | // *ioNumberDataPackets = 1;
19 | [self _fillBufferlist:ioData withBuffer:buffer packetDescription:outDataPacketDescription];
20 | return noErr;
21 | }
22 |
23 | AudioStreamBasicDescription LinearPCMStreamDescription()
24 | {
25 | AudioStreamBasicDescription destFormat;
26 | bzero(&destFormat, sizeof(AudioStreamBasicDescription));
27 | destFormat.mSampleRate = 44100.0;
28 | destFormat.mFormatID = kAudioFormatLinearPCM;
29 | destFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
30 |
31 | destFormat.mFramesPerPacket = 1;
32 | destFormat.mBytesPerPacket = 4;
33 | destFormat.mBytesPerFrame = 4;
34 | destFormat.mChannelsPerFrame = 2;
35 | destFormat.mBitsPerChannel = 16;
36 | destFormat.mReserved = 0;
37 | return destFormat;
38 | }
39 |
40 | @implementation SKAudioConverter
41 |
42 | - (instancetype)initWithSourceFormat:(AudioStreamBasicDescription *)sourceFormat
43 | {
44 | self = [super init];
45 | if (self) {
46 | audioStreamDescription = *sourceFormat;
47 | destFormat = LinearPCMStreamDescription();
48 | AudioConverterNew(&audioStreamDescription, &destFormat, &converter);
49 |
50 | UInt32 packetSize = 44100 * 4;
51 | renderBufferSize = packetSize;
52 | renderBufferList = (AudioBufferList *)calloc(1, sizeof(UInt32) + sizeof(AudioBuffer));
53 | renderBufferList->mNumberBuffers = 1;
54 | renderBufferList->mBuffers[0].mNumberChannels = 2;
55 | renderBufferList->mBuffers[0].mDataByteSize = packetSize;
56 | renderBufferList->mBuffers[0].mData = calloc(1, packetSize);
57 | }
58 | return self;
59 | }
60 |
61 | - (void)_fillBufferlist:(AudioBufferList *)ioData withBuffer:(SKAudioBuffer *)buffer packetDescription:(AudioStreamPacketDescription** )outDataPacketDescription
62 | {
63 | static AudioStreamPacketDescription aspdesc;
64 |
65 | AudioPacketInfo currentPacketInfo = buffer.currentPacketInfo;
66 |
67 | void *data = currentPacketInfo.data;
68 | UInt32 length = (UInt32)currentPacketInfo.packetDescription.mDataByteSize;
69 | ioData->mBuffers[0].mData = data;
70 | ioData->mBuffers[0].mDataByteSize = length;
71 | ioData->mNumberBuffers = 1;
72 |
73 | *outDataPacketDescription = &aspdesc;
74 | aspdesc.mDataByteSize = length;
75 | aspdesc.mStartOffset = 0;
76 | aspdesc.mVariableFramesInPacket = 1;
77 |
78 | [buffer movePacketReadIndex];
79 | }
80 |
81 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber buffer:(SKAudioBuffer *)inBuffer
82 | {
83 | UInt32 packetSize = inNumberOfFrames;
84 | NSArray *args = @[self, inBuffer];
85 | OSStatus status = noErr;
86 |
87 | status = AudioConverterFillComplexBuffer(converter, AudioConverterFiller, (__bridge void *)(args), &packetSize, renderBufferList, NULL);
88 |
89 | if (noErr == status && packetSize) {
90 | inIoData->mNumberBuffers = 1;
91 | inIoData->mBuffers[0].mNumberChannels = 2;
92 | inIoData->mBuffers[0].mDataByteSize = renderBufferList->mBuffers[0].mDataByteSize;
93 | inIoData->mBuffers[0].mData = renderBufferList->mBuffers[0].mData;
94 | status = noErr;
95 | }
96 | return status;
97 | }
98 |
99 | - (double)packetsPerSecond
100 | {
101 | if (!(audioStreamDescription.mFramesPerPacket > 0)) {
102 | return 0;
103 | }
104 | return audioStreamDescription.mSampleRate / audioStreamDescription.mFramesPerPacket;
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/SKAudioParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioParser.h
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class SKAudioParser;
13 |
14 | @protocol SKAudioParserDelegate
15 |
16 | - (void)audioStreamParser:(SKAudioParser *)inParser didObtainStreamDescription:(AudioStreamBasicDescription *)inDescription;
17 | - (void)audioStreamParser:(SKAudioParser *)inParser packetData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount;
18 |
19 | @end
20 |
21 | @interface SKAudioParser : NSObject
22 | {
23 | AudioFileStreamID audioFileStreamID;
24 | __weak id delegate;
25 | }
26 |
27 | - (void)parseData:(NSData *)inData;
28 |
29 | @property (weak, nonatomic) id delegate;
30 | @end
31 |
32 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/SKAudioParser.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioParser.m
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import "SKAudioParser.h"
10 |
11 | @implementation SKAudioParser
12 |
13 |
14 | void audioFileStreamPropertyListenerProc(void *inClientData, AudioFileStreamID inAudioFileStream, AudioFileStreamPropertyID inPropertyID, UInt32 *ioFlags)
15 | {
16 | /*
17 | kAudioFileStreamProperty_ReadyToProducePackets = 'redy',
18 | kAudioFileStreamProperty_FileFormat = 'ffmt',
19 | kAudioFileStreamProperty_DataFormat = 'dfmt',
20 | kAudioFileStreamProperty_FormatList = 'flst',
21 | kAudioFileStreamProperty_MagicCookieData = 'mgic',
22 | kAudioFileStreamProperty_AudioDataByteCount = 'bcnt',
23 | kAudioFileStreamProperty_AudioDataPacketCount = 'pcnt',
24 | kAudioFileStreamProperty_MaximumPacketSize = 'psze',
25 | kAudioFileStreamProperty_DataOffset = 'doff',
26 | kAudioFileStreamProperty_ChannelLayout = 'cmap',
27 | kAudioFileStreamProperty_PacketToFrame = 'pkfr',
28 | kAudioFileStreamProperty_FrameToPacket = 'frpk',
29 | kAudioFileStreamProperty_PacketToByte = 'pkby',
30 | kAudioFileStreamProperty_ByteToPacket = 'bypk',
31 | kAudioFileStreamProperty_PacketTableInfo = 'pnfo',
32 | kAudioFileStreamProperty_PacketSizeUpperBound = 'pkub',
33 | kAudioFileStreamProperty_AverageBytesPerPacket = 'abpp',
34 | kAudioFileStreamProperty_BitRate = 'brat',
35 | kAudioFileStreamProperty_InfoDictionary = 'info'
36 | */
37 | if (inPropertyID == 'dfmt') {
38 | AudioStreamBasicDescription description;
39 | UInt32 descriptionSize = sizeof(description);
40 | AudioFileStreamGetProperty(inAudioFileStream, inPropertyID, &descriptionSize, &description);
41 | [((__bridge SKAudioParser *)inClientData).delegate audioStreamParser:(__bridge SKAudioParser *)inClientData didObtainStreamDescription:&description];
42 | }
43 | }
44 |
45 |
46 | void audioFileStreamPacketsProc(void *inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void *inInputData, AudioStreamPacketDescription *inPacketDescriptions)
47 | {
48 | [((__bridge SKAudioParser *)inClientData).delegate audioStreamParser:((__bridge SKAudioParser *)inClientData) packetData:inInputData dataLength:inNumberBytes packetDescriptions:inPacketDescriptions packetsCount:inNumberPackets];
49 |
50 | }
51 |
52 | - (id)init
53 | {
54 | self = [super init];
55 | if (self) {
56 |
57 | AudioFileStreamOpen((__bridge void *)(self), audioFileStreamPropertyListenerProc, audioFileStreamPacketsProc, kAudioFileMP3Type, &audioFileStreamID);
58 |
59 | }
60 | return self;
61 | }
62 |
63 | - (void)parseData:(NSData *)inData
64 | {
65 | AudioFileStreamParseBytes(audioFileStreamID, (UInt32)[inData length], [inData bytes], 0);
66 | }
67 |
68 | @synthesize delegate;
69 | @end
70 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // MixPlaying
4 | //
5 | // Created by StevenKuo on 2015/11/19.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // MixPlaying
4 | //
5 | // Created by StevenKuo on 2015/11/19.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import
11 | #import
12 | #import "SKAudioParser.h"
13 | #import "SKAudioBuffer.h"
14 | #import "SKAudioConverter.h"
15 |
16 | @interface ViewController ()
17 | {
18 | AUGraph audioGraph;
19 | AUNode mixNode;
20 | AudioUnit mixAudioUnit;
21 | AUNode outputNode;
22 | AudioUnit outputAudioUnit;
23 |
24 | SKAudioParser *parser;
25 | SKAudioBuffer *buffer;
26 | SKAudioBuffer *buffer2;
27 | SKAudioParser *parser2;
28 |
29 | SKAudioConverter *converter;
30 | SKAudioConverter *converter2;
31 |
32 | NSURLSessionDataTask *task1;
33 | NSURLSessionDataTask *task2;
34 |
35 | BOOL firstComplete;
36 | IBOutlet UITextField *textFeild;
37 | IBOutlet UITextField *textFeild2;
38 | IBOutlet UILabel *tip;
39 | }
40 |
41 | @end
42 |
43 | static void MyAudioUnitPropertyListenerProc(void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope,AudioUnitElement inElement);
44 |
45 | static OSStatus RenderCallback(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
46 | static OSStatus RenderCallback2(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
47 |
48 | @implementation ViewController
49 |
50 | - (id)initWithCoder:(NSCoder *)aDecoder
51 | {
52 | self = [super initWithCoder:aDecoder];
53 | if (self) {
54 | parser = [[SKAudioParser alloc] init];
55 | parser.delegate = self;
56 |
57 | parser2 = [[SKAudioParser alloc] init];
58 | parser2.delegate = self;
59 |
60 | buffer = [[SKAudioBuffer alloc] init];
61 |
62 |
63 | buffer2 = [[SKAudioBuffer alloc] init];
64 |
65 |
66 | OSStatus status = noErr;
67 | status = NewAUGraph(&audioGraph);
68 | status = AUGraphOpen(audioGraph);
69 |
70 | AudioComponentDescription outputUnitDescription = [self outputUnitDescription];
71 | status = AUGraphAddNode(audioGraph, &outputUnitDescription, &outputNode);
72 | status = AUGraphNodeInfo(audioGraph, outputNode, &outputUnitDescription, &outputAudioUnit);
73 | UInt32 maxFPS = 4096;
74 | status = AudioUnitSetProperty(outputAudioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0,&maxFPS, sizeof(maxFPS));
75 |
76 | AudioComponentDescription mixUnitDescription = [self mixUnitDescription];
77 | status = AUGraphAddNode(audioGraph, &mixUnitDescription, &mixNode);
78 | status = AUGraphNodeInfo(audioGraph, mixNode, &mixUnitDescription, &mixAudioUnit);
79 | status = AudioUnitSetProperty(mixAudioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0,&maxFPS, sizeof(maxFPS));
80 |
81 | status = AUGraphConnectNodeInput(audioGraph, mixNode, 0, outputNode, 0);
82 |
83 | AudioStreamBasicDescription destFormat = LinearPCMStreamDescription();
84 |
85 | status = AudioUnitSetProperty(mixAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &destFormat, sizeof(destFormat));
86 |
87 | status = AudioUnitSetProperty(mixAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &destFormat, sizeof(destFormat));
88 |
89 | status = AudioUnitSetProperty(mixAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &destFormat, sizeof(destFormat));
90 |
91 | status = AudioUnitSetProperty(outputAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &destFormat, sizeof(destFormat));
92 |
93 | // status = AudioUnitSetParameter(mixAudioUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, 0, 0.5, 0);
94 | // status = AudioUnitSetParameter(mixAudioUnit, kMultiChannelMixerParam_Pan, kAudioUnitScope_Input, 0, 1, 1);
95 | // status = AudioUnitSetParameter(mixAudioUnit, kMultiChannelMixerParam_Pan, kAudioUnitScope_Input, 1, -1, 1);
96 |
97 |
98 | status = AudioUnitAddPropertyListener(outputAudioUnit, kAudioOutputUnitProperty_IsRunning, MyAudioUnitPropertyListenerProc, (__bridge void *)(self));
99 |
100 | AURenderCallbackStruct callbackStruct;
101 | callbackStruct.inputProcRefCon = (__bridge void *)(self);
102 | callbackStruct.inputProc = RenderCallback;
103 | status = AUGraphSetNodeInputCallback(audioGraph, mixNode, 0, &callbackStruct);
104 |
105 | AURenderCallbackStruct callbackStruct2;
106 | callbackStruct2.inputProcRefCon = (__bridge void *)(self);
107 | callbackStruct2.inputProc = RenderCallback2;
108 | status = AUGraphSetNodeInputCallback(audioGraph, mixNode, 1, &callbackStruct2);
109 |
110 | status = AUGraphInitialize(audioGraph);
111 | AudioOutputUnitStop(outputAudioUnit);
112 | }
113 | return self;
114 | }
115 |
116 | - (AudioComponentDescription)outputUnitDescription
117 | {
118 | AudioComponentDescription outputUnitDescription;
119 | bzero(&outputUnitDescription, sizeof(AudioComponentDescription));
120 | outputUnitDescription.componentType = kAudioUnitType_Output;
121 | outputUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
122 | outputUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
123 | outputUnitDescription.componentFlags = 0;
124 | outputUnitDescription.componentFlagsMask = 0;
125 | return outputUnitDescription;
126 | }
127 |
128 | - (AudioComponentDescription)mixUnitDescription
129 | {
130 | AudioComponentDescription mixerUnitDescription;
131 | bzero(&mixerUnitDescription, sizeof(AudioComponentDescription));
132 | mixerUnitDescription.componentType = kAudioUnitType_Mixer;
133 | mixerUnitDescription.componentSubType = kAudioUnitSubType_MultiChannelMixer;
134 | mixerUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
135 | mixerUnitDescription.componentFlags = 0;
136 | mixerUnitDescription.componentFlagsMask = 0;
137 | return mixerUnitDescription;
138 | }
139 |
140 |
141 | - (BOOL)textFieldShouldReturn:(UITextField *)textField {
142 | [textField resignFirstResponder];
143 | [textField setEnabled:NO];
144 | return YES;
145 | }
146 |
147 | - (void)textFieldDidEndEditing:(UITextField *)textField {
148 | [textField resignFirstResponder];
149 | [textField setEnabled:NO];
150 | if (textFeild.text.length != 0 && textFeild2.text.length != 0) {
151 | NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
152 | NSURLSessionConfiguration *myConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
153 | NSURLSession *operationSession = [NSURLSession sessionWithConfiguration:myConfiguration delegate:(id)self delegateQueue:operationQueue];
154 |
155 | NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:textFeild.text]];
156 | task1 = [operationSession dataTaskWithRequest:request];
157 | [task1 resume];
158 |
159 | NSURLRequest *request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:textFeild2.text]];
160 | task2 = [operationSession dataTaskWithRequest:request2];
161 | [task2 resume];
162 | }
163 |
164 | }
165 |
166 | - (BOOL)_outputNodePlaying
167 | {
168 | UInt32 property = 0;
169 | UInt32 propertySize = sizeof(property);
170 | AudioUnitGetProperty(outputAudioUnit, kAudioOutputUnitProperty_IsRunning, kAudioUnitScope_Global, 0, &property, &propertySize);
171 | return property != 0;
172 | }
173 |
174 | - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
175 | {
176 | completionHandler(NSURLSessionResponseAllow);
177 | }
178 |
179 | - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
180 | {
181 | dispatch_async(dispatch_get_main_queue(), ^{
182 | tip.text = @"receiving data...";
183 | tip.textColor = UIColor.blackColor;
184 | firstComplete = YES;
185 | });
186 | if ([dataTask isEqual:task1]) {
187 | [parser parseData:data];
188 | }
189 | else if ([dataTask isEqual:task2]) {
190 | if (![self _outputNodePlaying] && firstComplete) {
191 | OSStatus aError = AUGraphStart(audioGraph);
192 | aError = AudioOutputUnitStart(outputAudioUnit);
193 | }
194 | [parser2 parseData:data];
195 | }
196 | }
197 |
198 | - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
199 | {
200 | dispatch_async(dispatch_get_main_queue(), ^{
201 | if (error) {
202 | tip.textColor = UIColor.redColor;
203 | tip.text = @"Fail";
204 | textFeild.text = @"";
205 | [textFeild setEnabled:YES];
206 | return;
207 | }
208 | tip.text = @"";
209 | });
210 | }
211 |
212 | - (void)audioStreamParser:(SKAudioParser *)inParser didObtainStreamDescription:(AudioStreamBasicDescription *)inDescription
213 | {
214 | NSLog(@"mSampleRate: %f", inDescription->mSampleRate);
215 | NSLog(@"mFormatID: %u", (unsigned int)inDescription->mFormatID);
216 | NSLog(@"mFormatFlags: %u", (unsigned int)inDescription->mFormatFlags);
217 | NSLog(@"mBytesPerPacket: %u", (unsigned int)inDescription->mBytesPerPacket);
218 | NSLog(@"mFramesPerPacket: %u", (unsigned int)inDescription->mFramesPerPacket);
219 | NSLog(@"mBytesPerFrame: %u", (unsigned int)inDescription->mBytesPerFrame);
220 | NSLog(@"mChannelsPerFrame: %u", (unsigned int)inDescription->mChannelsPerFrame);
221 | NSLog(@"mBitsPerChannel: %u", (unsigned int)inDescription->mBitsPerChannel);
222 | NSLog(@"mReserved: %u", (unsigned int)inDescription->mReserved);
223 |
224 | if ([inParser isEqual:parser]) {
225 | converter = [[SKAudioConverter alloc] initWithSourceFormat:inDescription];
226 | }
227 | else if ([inParser isEqual:parser2]) {
228 | converter2 = [[SKAudioConverter alloc] initWithSourceFormat:inDescription];
229 | }
230 | }
231 | - (void)audioStreamParser:(SKAudioParser *)inParser packetData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount
232 | {
233 | if ([inParser isEqual:parser]) {
234 | [buffer storePacketData:inBytes dataLength:inLength packetDescriptions:inPacketDescriptions packetsCount:inPacketsCount];
235 | }
236 | else if ([inParser isEqual:parser2]){
237 | [buffer2 storePacketData:inBytes dataLength:inLength packetDescriptions:inPacketDescriptions packetsCount:inPacketsCount];
238 | }
239 | }
240 |
241 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber
242 | {
243 | if (buffer.availablePacketCount < converter.packetsPerSecond * 4) {
244 | return -1;
245 | }
246 | return [converter requestNumberOfFrames:inNumberOfFrames ioData:inIoData busNumber:inBusNumber buffer:buffer];
247 | }
248 |
249 | - (OSStatus)requestNumberOfFrames2:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber
250 | {
251 | if (buffer2.availablePacketCount < converter2.packetsPerSecond * 4) {
252 | return -1;
253 | }
254 | return [converter2 requestNumberOfFrames:inNumberOfFrames ioData:inIoData busNumber:inBusNumber buffer:buffer2];
255 | }
256 |
257 | void MyAudioUnitPropertyListenerProc(void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope,AudioUnitElement inElement)
258 | {
259 |
260 | }
261 |
262 | static OSStatus RenderCallback(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
263 | {
264 | ViewController *self = (__bridge ViewController *)userData;
265 |
266 | OSStatus status = [self requestNumberOfFrames:inNumberFrames ioData:ioData busNumber:inBusNumber];
267 |
268 | return status;
269 | }
270 |
271 | static OSStatus RenderCallback2(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
272 | {
273 | ViewController *self = (__bridge ViewController *)userData;
274 |
275 | OSStatus status = [self requestNumberOfFrames2:inNumberFrames ioData:ioData busNumber:inBusNumber];
276 |
277 | return status;
278 | }
279 |
280 | @end
281 |
--------------------------------------------------------------------------------
/AudioUnitSample/MixPlaying/MixPlaying/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // MixPlaying
4 | //
5 | // Created by StevenKuo on 2015/11/19.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevenKuo/AudioUnitSample/b50c8111600d283cbde02ce48f1ae36b3aa49f61/AudioUnitSample/RemoteInput/.DS_Store
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9C7E4A971C0EA8ED008F91F2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7E4A961C0EA8ED008F91F2 /* main.m */; };
11 | 9C7E4A9A1C0EA8ED008F91F2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7E4A991C0EA8ED008F91F2 /* AppDelegate.m */; };
12 | 9C7E4A9D1C0EA8ED008F91F2 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7E4A9C1C0EA8ED008F91F2 /* ViewController.m */; };
13 | 9C7E4AA01C0EA8ED008F91F2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C7E4A9E1C0EA8ED008F91F2 /* Main.storyboard */; };
14 | 9C7E4AA21C0EA8ED008F91F2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9C7E4AA11C0EA8ED008F91F2 /* Assets.xcassets */; };
15 | 9C7E4AA51C0EA8ED008F91F2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C7E4AA31C0EA8ED008F91F2 /* LaunchScreen.storyboard */; };
16 | 9C7E4AB01C0EA93E008F91F2 /* SKAudioBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7E4AAD1C0EA93E008F91F2 /* SKAudioBuffer.m */; };
17 | 9C7E4AB11C0EA93E008F91F2 /* SKAudioParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7E4AAF1C0EA93E008F91F2 /* SKAudioParser.m */; };
18 | 9C7E4AB41C0EA970008F91F2 /* SKAudioConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7E4AB31C0EA970008F91F2 /* SKAudioConverter.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | 9C7E4A921C0EA8ED008F91F2 /* RemoteInput.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RemoteInput.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | 9C7E4A961C0EA8ED008F91F2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
24 | 9C7E4A981C0EA8ED008F91F2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
25 | 9C7E4A991C0EA8ED008F91F2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
26 | 9C7E4A9B1C0EA8ED008F91F2 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
27 | 9C7E4A9C1C0EA8ED008F91F2 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
28 | 9C7E4A9F1C0EA8ED008F91F2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
29 | 9C7E4AA11C0EA8ED008F91F2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
30 | 9C7E4AA41C0EA8ED008F91F2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
31 | 9C7E4AA61C0EA8ED008F91F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
32 | 9C7E4AAC1C0EA93E008F91F2 /* SKAudioBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SKAudioBuffer.h; path = RemoteInput/SKAudioBuffer.h; sourceTree = ""; };
33 | 9C7E4AAD1C0EA93E008F91F2 /* SKAudioBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SKAudioBuffer.m; path = RemoteInput/SKAudioBuffer.m; sourceTree = ""; };
34 | 9C7E4AAE1C0EA93E008F91F2 /* SKAudioParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SKAudioParser.h; path = RemoteInput/SKAudioParser.h; sourceTree = ""; };
35 | 9C7E4AAF1C0EA93E008F91F2 /* SKAudioParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SKAudioParser.m; path = RemoteInput/SKAudioParser.m; sourceTree = ""; };
36 | 9C7E4AB21C0EA970008F91F2 /* SKAudioConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SKAudioConverter.h; path = RemoteInput/SKAudioConverter.h; sourceTree = ""; };
37 | 9C7E4AB31C0EA970008F91F2 /* SKAudioConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SKAudioConverter.m; path = RemoteInput/SKAudioConverter.m; sourceTree = ""; };
38 | /* End PBXFileReference section */
39 |
40 | /* Begin PBXFrameworksBuildPhase section */
41 | 9C7E4A8F1C0EA8ED008F91F2 /* Frameworks */ = {
42 | isa = PBXFrameworksBuildPhase;
43 | buildActionMask = 2147483647;
44 | files = (
45 | );
46 | runOnlyForDeploymentPostprocessing = 0;
47 | };
48 | /* End PBXFrameworksBuildPhase section */
49 |
50 | /* Begin PBXGroup section */
51 | 9C7E4A891C0EA8ED008F91F2 = {
52 | isa = PBXGroup;
53 | children = (
54 | 9C7E4AB21C0EA970008F91F2 /* SKAudioConverter.h */,
55 | 9C7E4AB31C0EA970008F91F2 /* SKAudioConverter.m */,
56 | 9C7E4AAC1C0EA93E008F91F2 /* SKAudioBuffer.h */,
57 | 9C7E4AAD1C0EA93E008F91F2 /* SKAudioBuffer.m */,
58 | 9C7E4AAE1C0EA93E008F91F2 /* SKAudioParser.h */,
59 | 9C7E4AAF1C0EA93E008F91F2 /* SKAudioParser.m */,
60 | 9C7E4A941C0EA8ED008F91F2 /* RemoteInput */,
61 | 9C7E4A931C0EA8ED008F91F2 /* Products */,
62 | );
63 | sourceTree = "";
64 | };
65 | 9C7E4A931C0EA8ED008F91F2 /* Products */ = {
66 | isa = PBXGroup;
67 | children = (
68 | 9C7E4A921C0EA8ED008F91F2 /* RemoteInput.app */,
69 | );
70 | name = Products;
71 | sourceTree = "";
72 | };
73 | 9C7E4A941C0EA8ED008F91F2 /* RemoteInput */ = {
74 | isa = PBXGroup;
75 | children = (
76 | 9C7E4A981C0EA8ED008F91F2 /* AppDelegate.h */,
77 | 9C7E4A991C0EA8ED008F91F2 /* AppDelegate.m */,
78 | 9C7E4A9B1C0EA8ED008F91F2 /* ViewController.h */,
79 | 9C7E4A9C1C0EA8ED008F91F2 /* ViewController.m */,
80 | 9C7E4A9E1C0EA8ED008F91F2 /* Main.storyboard */,
81 | 9C7E4AA11C0EA8ED008F91F2 /* Assets.xcassets */,
82 | 9C7E4AA31C0EA8ED008F91F2 /* LaunchScreen.storyboard */,
83 | 9C7E4AA61C0EA8ED008F91F2 /* Info.plist */,
84 | 9C7E4A951C0EA8ED008F91F2 /* Supporting Files */,
85 | );
86 | path = RemoteInput;
87 | sourceTree = "";
88 | };
89 | 9C7E4A951C0EA8ED008F91F2 /* Supporting Files */ = {
90 | isa = PBXGroup;
91 | children = (
92 | 9C7E4A961C0EA8ED008F91F2 /* main.m */,
93 | );
94 | name = "Supporting Files";
95 | sourceTree = "";
96 | };
97 | /* End PBXGroup section */
98 |
99 | /* Begin PBXNativeTarget section */
100 | 9C7E4A911C0EA8ED008F91F2 /* RemoteInput */ = {
101 | isa = PBXNativeTarget;
102 | buildConfigurationList = 9C7E4AA91C0EA8ED008F91F2 /* Build configuration list for PBXNativeTarget "RemoteInput" */;
103 | buildPhases = (
104 | 9C7E4A8E1C0EA8ED008F91F2 /* Sources */,
105 | 9C7E4A8F1C0EA8ED008F91F2 /* Frameworks */,
106 | 9C7E4A901C0EA8ED008F91F2 /* Resources */,
107 | );
108 | buildRules = (
109 | );
110 | dependencies = (
111 | );
112 | name = RemoteInput;
113 | productName = RemoteInput;
114 | productReference = 9C7E4A921C0EA8ED008F91F2 /* RemoteInput.app */;
115 | productType = "com.apple.product-type.application";
116 | };
117 | /* End PBXNativeTarget section */
118 |
119 | /* Begin PBXProject section */
120 | 9C7E4A8A1C0EA8ED008F91F2 /* Project object */ = {
121 | isa = PBXProject;
122 | attributes = {
123 | LastUpgradeCheck = 0710;
124 | ORGANIZATIONNAME = StevenKuo;
125 | TargetAttributes = {
126 | 9C7E4A911C0EA8ED008F91F2 = {
127 | CreatedOnToolsVersion = 7.1.1;
128 | DevelopmentTeam = Z48FVJQBYK;
129 | };
130 | };
131 | };
132 | buildConfigurationList = 9C7E4A8D1C0EA8ED008F91F2 /* Build configuration list for PBXProject "RemoteInput" */;
133 | compatibilityVersion = "Xcode 3.2";
134 | developmentRegion = English;
135 | hasScannedForEncodings = 0;
136 | knownRegions = (
137 | en,
138 | Base,
139 | );
140 | mainGroup = 9C7E4A891C0EA8ED008F91F2;
141 | productRefGroup = 9C7E4A931C0EA8ED008F91F2 /* Products */;
142 | projectDirPath = "";
143 | projectRoot = "";
144 | targets = (
145 | 9C7E4A911C0EA8ED008F91F2 /* RemoteInput */,
146 | );
147 | };
148 | /* End PBXProject section */
149 |
150 | /* Begin PBXResourcesBuildPhase section */
151 | 9C7E4A901C0EA8ED008F91F2 /* Resources */ = {
152 | isa = PBXResourcesBuildPhase;
153 | buildActionMask = 2147483647;
154 | files = (
155 | 9C7E4AA51C0EA8ED008F91F2 /* LaunchScreen.storyboard in Resources */,
156 | 9C7E4AA21C0EA8ED008F91F2 /* Assets.xcassets in Resources */,
157 | 9C7E4AA01C0EA8ED008F91F2 /* Main.storyboard in Resources */,
158 | );
159 | runOnlyForDeploymentPostprocessing = 0;
160 | };
161 | /* End PBXResourcesBuildPhase section */
162 |
163 | /* Begin PBXSourcesBuildPhase section */
164 | 9C7E4A8E1C0EA8ED008F91F2 /* Sources */ = {
165 | isa = PBXSourcesBuildPhase;
166 | buildActionMask = 2147483647;
167 | files = (
168 | 9C7E4AB01C0EA93E008F91F2 /* SKAudioBuffer.m in Sources */,
169 | 9C7E4AB41C0EA970008F91F2 /* SKAudioConverter.m in Sources */,
170 | 9C7E4A9D1C0EA8ED008F91F2 /* ViewController.m in Sources */,
171 | 9C7E4A9A1C0EA8ED008F91F2 /* AppDelegate.m in Sources */,
172 | 9C7E4AB11C0EA93E008F91F2 /* SKAudioParser.m in Sources */,
173 | 9C7E4A971C0EA8ED008F91F2 /* main.m in Sources */,
174 | );
175 | runOnlyForDeploymentPostprocessing = 0;
176 | };
177 | /* End PBXSourcesBuildPhase section */
178 |
179 | /* Begin PBXVariantGroup section */
180 | 9C7E4A9E1C0EA8ED008F91F2 /* Main.storyboard */ = {
181 | isa = PBXVariantGroup;
182 | children = (
183 | 9C7E4A9F1C0EA8ED008F91F2 /* Base */,
184 | );
185 | name = Main.storyboard;
186 | sourceTree = "";
187 | };
188 | 9C7E4AA31C0EA8ED008F91F2 /* LaunchScreen.storyboard */ = {
189 | isa = PBXVariantGroup;
190 | children = (
191 | 9C7E4AA41C0EA8ED008F91F2 /* Base */,
192 | );
193 | name = LaunchScreen.storyboard;
194 | sourceTree = "";
195 | };
196 | /* End PBXVariantGroup section */
197 |
198 | /* Begin XCBuildConfiguration section */
199 | 9C7E4AA71C0EA8ED008F91F2 /* Debug */ = {
200 | isa = XCBuildConfiguration;
201 | buildSettings = {
202 | ALWAYS_SEARCH_USER_PATHS = NO;
203 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
204 | CLANG_CXX_LIBRARY = "libc++";
205 | CLANG_ENABLE_MODULES = YES;
206 | CLANG_ENABLE_OBJC_ARC = YES;
207 | CLANG_WARN_BOOL_CONVERSION = YES;
208 | CLANG_WARN_CONSTANT_CONVERSION = YES;
209 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
210 | CLANG_WARN_EMPTY_BODY = YES;
211 | CLANG_WARN_ENUM_CONVERSION = YES;
212 | CLANG_WARN_INT_CONVERSION = YES;
213 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
214 | CLANG_WARN_UNREACHABLE_CODE = YES;
215 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
216 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
217 | COPY_PHASE_STRIP = NO;
218 | DEBUG_INFORMATION_FORMAT = dwarf;
219 | ENABLE_STRICT_OBJC_MSGSEND = YES;
220 | ENABLE_TESTABILITY = YES;
221 | GCC_C_LANGUAGE_STANDARD = gnu99;
222 | GCC_DYNAMIC_NO_PIC = NO;
223 | GCC_NO_COMMON_BLOCKS = YES;
224 | GCC_OPTIMIZATION_LEVEL = 0;
225 | GCC_PREPROCESSOR_DEFINITIONS = (
226 | "DEBUG=1",
227 | "$(inherited)",
228 | );
229 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
230 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
231 | GCC_WARN_UNDECLARED_SELECTOR = YES;
232 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
233 | GCC_WARN_UNUSED_FUNCTION = YES;
234 | GCC_WARN_UNUSED_VARIABLE = YES;
235 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
236 | MTL_ENABLE_DEBUG_INFO = YES;
237 | ONLY_ACTIVE_ARCH = YES;
238 | SDKROOT = iphoneos;
239 | TARGETED_DEVICE_FAMILY = "1,2";
240 | };
241 | name = Debug;
242 | };
243 | 9C7E4AA81C0EA8ED008F91F2 /* Release */ = {
244 | isa = XCBuildConfiguration;
245 | buildSettings = {
246 | ALWAYS_SEARCH_USER_PATHS = NO;
247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
248 | CLANG_CXX_LIBRARY = "libc++";
249 | CLANG_ENABLE_MODULES = YES;
250 | CLANG_ENABLE_OBJC_ARC = YES;
251 | CLANG_WARN_BOOL_CONVERSION = YES;
252 | CLANG_WARN_CONSTANT_CONVERSION = YES;
253 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
254 | CLANG_WARN_EMPTY_BODY = YES;
255 | CLANG_WARN_ENUM_CONVERSION = YES;
256 | CLANG_WARN_INT_CONVERSION = YES;
257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
258 | CLANG_WARN_UNREACHABLE_CODE = YES;
259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
260 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
261 | COPY_PHASE_STRIP = NO;
262 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
263 | ENABLE_NS_ASSERTIONS = NO;
264 | ENABLE_STRICT_OBJC_MSGSEND = YES;
265 | GCC_C_LANGUAGE_STANDARD = gnu99;
266 | GCC_NO_COMMON_BLOCKS = YES;
267 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
268 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
269 | GCC_WARN_UNDECLARED_SELECTOR = YES;
270 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
271 | GCC_WARN_UNUSED_FUNCTION = YES;
272 | GCC_WARN_UNUSED_VARIABLE = YES;
273 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
274 | MTL_ENABLE_DEBUG_INFO = NO;
275 | SDKROOT = iphoneos;
276 | TARGETED_DEVICE_FAMILY = "1,2";
277 | VALIDATE_PRODUCT = YES;
278 | };
279 | name = Release;
280 | };
281 | 9C7E4AAA1C0EA8ED008F91F2 /* Debug */ = {
282 | isa = XCBuildConfiguration;
283 | buildSettings = {
284 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
285 | CODE_SIGN_IDENTITY = "iPhone Developer";
286 | INFOPLIST_FILE = RemoteInput/Info.plist;
287 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
288 | PRODUCT_BUNDLE_IDENTIFIER = SK.RemoteInput;
289 | PRODUCT_NAME = "$(TARGET_NAME)";
290 | };
291 | name = Debug;
292 | };
293 | 9C7E4AAB1C0EA8ED008F91F2 /* Release */ = {
294 | isa = XCBuildConfiguration;
295 | buildSettings = {
296 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
297 | CODE_SIGN_IDENTITY = "iPhone Developer";
298 | INFOPLIST_FILE = RemoteInput/Info.plist;
299 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
300 | PRODUCT_BUNDLE_IDENTIFIER = SK.RemoteInput;
301 | PRODUCT_NAME = "$(TARGET_NAME)";
302 | };
303 | name = Release;
304 | };
305 | /* End XCBuildConfiguration section */
306 |
307 | /* Begin XCConfigurationList section */
308 | 9C7E4A8D1C0EA8ED008F91F2 /* Build configuration list for PBXProject "RemoteInput" */ = {
309 | isa = XCConfigurationList;
310 | buildConfigurations = (
311 | 9C7E4AA71C0EA8ED008F91F2 /* Debug */,
312 | 9C7E4AA81C0EA8ED008F91F2 /* Release */,
313 | );
314 | defaultConfigurationIsVisible = 0;
315 | defaultConfigurationName = Release;
316 | };
317 | 9C7E4AA91C0EA8ED008F91F2 /* Build configuration list for PBXNativeTarget "RemoteInput" */ = {
318 | isa = XCConfigurationList;
319 | buildConfigurations = (
320 | 9C7E4AAA1C0EA8ED008F91F2 /* Debug */,
321 | 9C7E4AAB1C0EA8ED008F91F2 /* Release */,
322 | );
323 | defaultConfigurationIsVisible = 0;
324 | };
325 | /* End XCConfigurationList section */
326 | };
327 | rootObject = 9C7E4A8A1C0EA8ED008F91F2 /* Project object */;
328 | }
329 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // RemoteInput
4 | //
5 | // Created by StevenKuo on 2015/12/2.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // RemoteInput
4 | //
5 | // Created by StevenKuo on 2015/12/2.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
40 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSAppTransportSecurity
6 |
7 | NSExceptionDomains
8 |
9 | s3-us-west-2.amazonaws.com
10 |
11 | NSExceptionRequiresForwardSecrecy
12 |
13 | NSIncludesSubdomains
14 |
15 |
16 |
17 |
18 | CFBundleDevelopmentRegion
19 | en
20 | CFBundleExecutable
21 | $(EXECUTABLE_NAME)
22 | CFBundleIdentifier
23 | $(PRODUCT_BUNDLE_IDENTIFIER)
24 | CFBundleInfoDictionaryVersion
25 | 6.0
26 | CFBundleName
27 | $(PRODUCT_NAME)
28 | CFBundlePackageType
29 | APPL
30 | CFBundleShortVersionString
31 | 1.0
32 | CFBundleSignature
33 | ????
34 | CFBundleVersion
35 | 1
36 | LSRequiresIPhoneOS
37 |
38 | UILaunchStoryboardName
39 | LaunchScreen
40 | UIMainStoryboardFile
41 | Main
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/SKAudioBuffer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioBuffer.h
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | typedef struct {
13 | AudioStreamPacketDescription packetDescription;
14 | void *data;
15 | } AudioPacketInfo;
16 |
17 | @class SKAudioBuffer;
18 |
19 | @protocol SKAudioBufferDelegate
20 |
21 | - (AudioStreamBasicDescription)usedAudioStreamBasicDescription;
22 | - (void)audioBufferDidBeginReadPacket:(SKAudioBuffer *)inBuffer;
23 | @end
24 |
25 | @interface SKAudioBuffer : NSObject
26 | {
27 | __weak id delegate;
28 |
29 | AudioPacketInfo *packets;
30 | size_t packetWriteIndex;
31 | size_t packetReadIndex;
32 | size_t packetCount;
33 |
34 | NSMutableData *audioData;
35 | NSMutableData *packetDescData;
36 | NSUInteger packetReadHead;
37 | NSUInteger readPacketIndex;
38 | }
39 |
40 |
41 | - (void)storePacketData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount;
42 | - (void)movePacketReadIndex;
43 |
44 | @property (readonly, nonatomic) size_t availablePacketCount;
45 | @property (weak, nonatomic) id delegate;
46 | @property (readonly, nonatomic) AudioPacketInfo currentPacketInfo;
47 | @end
48 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/SKAudioBuffer.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioBuffer.m
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import "SKAudioBuffer.h"
10 |
11 | @implementation SKAudioBuffer
12 |
13 | - (id)init
14 | {
15 | self = [super init];
16 | if (self) {
17 |
18 | packetCount = 2048;
19 | packets = (AudioPacketInfo *)calloc(packetCount, sizeof(AudioPacketInfo));
20 |
21 | audioData = [[NSMutableData alloc] init];
22 | packetDescData = [[NSMutableData alloc] init];
23 | }
24 | return self;
25 | }
26 |
27 |
28 | - (void)storePacketData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount
29 | {
30 | // for (NSUInteger packetIndex = 0; packetIndex < inPacketsCount ; packetIndex ++) {
31 | // inPacketDescriptions[packetIndex].mStartOffset += audioData.length;
32 | // }
33 | //
34 | // @synchronized (self) {
35 | // [audioData appendBytes:inBytes length:inLength];
36 | // [packetDescData appendBytes:inPacketDescriptions length:sizeof(AudioStreamPacketDescription) * inPacketsCount];
37 | // availablePacketCount += inPacketsCount;
38 | // }
39 |
40 | @synchronized (self) {
41 |
42 | for (size_t index = 0; index < inPacketsCount; index ++) {
43 |
44 | if (packetWriteIndex >= packetCount) {
45 | size_t oldSize = packetCount * sizeof(AudioPacketInfo);
46 | packetCount = packetCount * 2;
47 | packets = (AudioPacketInfo *)realloc(packets, packetCount * sizeof(AudioPacketInfo));
48 | bzero((void *)packets + oldSize, oldSize);
49 | }
50 | AudioStreamPacketDescription emptyDescription;
51 |
52 | if (!inPacketDescriptions) {
53 | emptyDescription.mStartOffset = index;
54 | emptyDescription.mDataByteSize = 1;
55 | emptyDescription.mVariableFramesInPacket = 0;
56 | }
57 |
58 | AudioStreamPacketDescription *currentDescription = inPacketDescriptions ? &(inPacketDescriptions[index]) : &emptyDescription;
59 |
60 | AudioPacketInfo *nextInfo = &packets[packetWriteIndex];
61 | if (nextInfo->data) {
62 | free(nextInfo->data);
63 | nextInfo->data = NULL;
64 | }
65 | nextInfo->data = malloc(currentDescription->mDataByteSize);
66 | NSAssert(nextInfo->data, @"Must allocate memory for current packet");
67 | memcpy(nextInfo->data, inBytes + currentDescription->mStartOffset, currentDescription->mDataByteSize);
68 | memcpy(&nextInfo->packetDescription, currentDescription, sizeof(AudioStreamPacketDescription));
69 |
70 | packetWriteIndex++;
71 |
72 | _availablePacketCount++;
73 | }
74 | }
75 | }
76 |
77 | - (void)setPacketReadIndex:(size_t)inNewIndex
78 | {
79 | size_t max = _availablePacketCount;
80 |
81 | if (inNewIndex > max) {
82 | packetReadIndex = max;
83 | return;
84 | }
85 |
86 | if (inNewIndex < packetWriteIndex) {
87 | packetReadIndex = inNewIndex;
88 | }
89 | else {
90 | packetReadIndex = packetWriteIndex;
91 | }
92 | }
93 |
94 | - (void)movePacketReadIndex
95 | {
96 | [self setPacketReadIndex:packetReadIndex + 1];
97 | }
98 |
99 | - (AudioPacketInfo)currentPacketInfo
100 | {
101 | // @synchronized (self) {
102 | // if (readPacketIndex >= availablePacketCount) {
103 | // inCallback(nil, 0, nil, YES);
104 | // return;
105 | // }
106 | // if (readPacketIndex == 0) {
107 | // [delegate audioBufferDidBeginReadPacket:self];
108 | // }
109 | //
110 | // AudioStreamPacketDescription* packetDescriptions = (AudioStreamPacketDescription* )packetDescData.bytes;
111 | //
112 | // AudioPacketInfo *packet = (AudioPacketInfo *)calloc(1, sizeof(AudioPacketInfo));
113 | // packet->data = malloc(packetDescriptions[readPacketIndex].mDataByteSize);
114 | // memcpy(packet->data, audioData.bytes + packetDescriptions[readPacketIndex].mStartOffset, packetDescriptions[readPacketIndex].mDataByteSize);
115 | // memcpy(&packet->packetDescription, &packetDescriptions[readPacketIndex], sizeof(AudioStreamPacketDescription));
116 | //
117 | // readPacketIndex ++;
118 | //
119 | // return *packet;
120 | // }
121 | return packets[packetReadIndex];
122 | }
123 |
124 | @synthesize delegate;
125 | @synthesize currentPacketInfo;
126 | @end
127 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/SKAudioConverter.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioConverter.h
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "SKAudioBuffer.h"
12 |
13 | @interface SKAudioConverter : NSObject
14 | {
15 | AudioStreamBasicDescription audioStreamDescription;
16 | AudioStreamBasicDescription destFormat;
17 | AudioConverterRef converter;
18 | AudioBufferList *renderBufferList;
19 | UInt32 renderBufferSize;
20 | }
21 |
22 | AudioStreamBasicDescription LinearPCMStreamDescription();
23 |
24 | - (instancetype)initWithSourceFormat:(AudioStreamBasicDescription *)sourceFormat;
25 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber buffer:(SKAudioBuffer *)inBuffer;
26 |
27 | - (void)_fillBufferlist:(AudioBufferList *)ioData withBuffer:(SKAudioBuffer *)buffer packetDescription:(AudioStreamPacketDescription** )outDataPacketDescription;
28 | @property (readonly, nonatomic) double packetsPerSecond;
29 | @end
30 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/SKAudioConverter.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioConverter.m
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "SKAudioConverter.h"
10 |
11 | static OSStatus AudioConverterFiller(AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData);
12 |
13 | OSStatus AudioConverterFiller (AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData)
14 | {
15 | NSArray *args = (__bridge NSArray *)inUserData;
16 | SKAudioConverter *self = args[0];
17 | SKAudioBuffer *buffer = args[1];
18 | // *ioNumberDataPackets = 1;
19 | [self _fillBufferlist:ioData withBuffer:buffer packetDescription:outDataPacketDescription];
20 | return noErr;
21 | }
22 |
23 | AudioStreamBasicDescription LinearPCMStreamDescription()
24 | {
25 | AudioStreamBasicDescription destFormat;
26 | bzero(&destFormat, sizeof(AudioStreamBasicDescription));
27 | destFormat.mSampleRate = 44100.0;
28 | destFormat.mFormatID = kAudioFormatLinearPCM;
29 | destFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
30 |
31 | destFormat.mFramesPerPacket = 1;
32 | destFormat.mBytesPerPacket = 4;
33 | destFormat.mBytesPerFrame = 4;
34 | destFormat.mChannelsPerFrame = 2;
35 | destFormat.mBitsPerChannel = 16;
36 | destFormat.mReserved = 0;
37 | return destFormat;
38 | }
39 |
40 | @implementation SKAudioConverter
41 |
42 | - (instancetype)initWithSourceFormat:(AudioStreamBasicDescription *)sourceFormat
43 | {
44 | self = [super init];
45 | if (self) {
46 | audioStreamDescription = *sourceFormat;
47 | destFormat = LinearPCMStreamDescription();
48 | AudioConverterNew(&audioStreamDescription, &destFormat, &converter);
49 |
50 | UInt32 packetSize = 44100 * 4;
51 | renderBufferSize = packetSize;
52 | renderBufferList = (AudioBufferList *)calloc(1, sizeof(UInt32) + sizeof(AudioBuffer));
53 | renderBufferList->mNumberBuffers = 1;
54 | renderBufferList->mBuffers[0].mNumberChannels = 2;
55 | renderBufferList->mBuffers[0].mDataByteSize = packetSize;
56 | renderBufferList->mBuffers[0].mData = calloc(1, packetSize);
57 | }
58 | return self;
59 | }
60 |
61 | - (void)_fillBufferlist:(AudioBufferList *)ioData withBuffer:(SKAudioBuffer *)buffer packetDescription:(AudioStreamPacketDescription** )outDataPacketDescription
62 | {
63 | static AudioStreamPacketDescription aspdesc;
64 |
65 | AudioPacketInfo currentPacketInfo = buffer.currentPacketInfo;
66 |
67 | void *data = currentPacketInfo.data;
68 | UInt32 length = (UInt32)currentPacketInfo.packetDescription.mDataByteSize;
69 | ioData->mBuffers[0].mData = data;
70 | ioData->mBuffers[0].mDataByteSize = length;
71 | ioData->mNumberBuffers = 1;
72 |
73 | *outDataPacketDescription = &aspdesc;
74 | aspdesc.mDataByteSize = length;
75 | aspdesc.mStartOffset = 0;
76 | aspdesc.mVariableFramesInPacket = 1;
77 |
78 | [buffer movePacketReadIndex];
79 | }
80 |
81 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber buffer:(SKAudioBuffer *)inBuffer
82 | {
83 | UInt32 packetSize = inNumberOfFrames;
84 | NSArray *args = @[self, inBuffer];
85 | OSStatus status = noErr;
86 |
87 | status = AudioConverterFillComplexBuffer(converter, AudioConverterFiller, (__bridge void *)(args), &packetSize, renderBufferList, NULL);
88 |
89 | if (noErr == status && packetSize) {
90 | inIoData->mNumberBuffers = 1;
91 | inIoData->mBuffers[0].mNumberChannels = 2;
92 | inIoData->mBuffers[0].mDataByteSize = renderBufferList->mBuffers[0].mDataByteSize;
93 | inIoData->mBuffers[0].mData = renderBufferList->mBuffers[0].mData;
94 | status = noErr;
95 | }
96 | return status;
97 | }
98 |
99 | - (double)packetsPerSecond
100 | {
101 | if (!(audioStreamDescription.mFramesPerPacket > 0)) {
102 | return 0;
103 | }
104 | return audioStreamDescription.mSampleRate / audioStreamDescription.mFramesPerPacket;
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/SKAudioParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioParser.h
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class SKAudioParser;
13 |
14 | @protocol SKAudioParserDelegate
15 |
16 | - (void)audioStreamParser:(SKAudioParser *)inParser didObtainStreamDescription:(AudioStreamBasicDescription *)inDescription;
17 | - (void)audioStreamParser:(SKAudioParser *)inParser packetData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount;
18 |
19 | @end
20 |
21 | @interface SKAudioParser : NSObject
22 | {
23 | AudioFileStreamID audioFileStreamID;
24 | __weak id delegate;
25 | }
26 |
27 | - (void)parseData:(NSData *)inData;
28 |
29 | @property (weak, nonatomic) id delegate;
30 | @end
31 |
32 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/SKAudioParser.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioParser.m
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import "SKAudioParser.h"
10 |
11 | @implementation SKAudioParser
12 |
13 |
14 | void audioFileStreamPropertyListenerProc(void *inClientData, AudioFileStreamID inAudioFileStream, AudioFileStreamPropertyID inPropertyID, UInt32 *ioFlags)
15 | {
16 | /*
17 | kAudioFileStreamProperty_ReadyToProducePackets = 'redy',
18 | kAudioFileStreamProperty_FileFormat = 'ffmt',
19 | kAudioFileStreamProperty_DataFormat = 'dfmt',
20 | kAudioFileStreamProperty_FormatList = 'flst',
21 | kAudioFileStreamProperty_MagicCookieData = 'mgic',
22 | kAudioFileStreamProperty_AudioDataByteCount = 'bcnt',
23 | kAudioFileStreamProperty_AudioDataPacketCount = 'pcnt',
24 | kAudioFileStreamProperty_MaximumPacketSize = 'psze',
25 | kAudioFileStreamProperty_DataOffset = 'doff',
26 | kAudioFileStreamProperty_ChannelLayout = 'cmap',
27 | kAudioFileStreamProperty_PacketToFrame = 'pkfr',
28 | kAudioFileStreamProperty_FrameToPacket = 'frpk',
29 | kAudioFileStreamProperty_PacketToByte = 'pkby',
30 | kAudioFileStreamProperty_ByteToPacket = 'bypk',
31 | kAudioFileStreamProperty_PacketTableInfo = 'pnfo',
32 | kAudioFileStreamProperty_PacketSizeUpperBound = 'pkub',
33 | kAudioFileStreamProperty_AverageBytesPerPacket = 'abpp',
34 | kAudioFileStreamProperty_BitRate = 'brat',
35 | kAudioFileStreamProperty_InfoDictionary = 'info'
36 | */
37 | if (inPropertyID == 'dfmt') {
38 | AudioStreamBasicDescription description;
39 | UInt32 descriptionSize = sizeof(description);
40 | AudioFileStreamGetProperty(inAudioFileStream, inPropertyID, &descriptionSize, &description);
41 | [((__bridge SKAudioParser *)inClientData).delegate audioStreamParser:(__bridge SKAudioParser *)inClientData didObtainStreamDescription:&description];
42 | }
43 | }
44 |
45 |
46 | void audioFileStreamPacketsProc(void *inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void *inInputData, AudioStreamPacketDescription *inPacketDescriptions)
47 | {
48 | [((__bridge SKAudioParser *)inClientData).delegate audioStreamParser:((__bridge SKAudioParser *)inClientData) packetData:inInputData dataLength:inNumberBytes packetDescriptions:inPacketDescriptions packetsCount:inNumberPackets];
49 |
50 | }
51 |
52 | - (id)init
53 | {
54 | self = [super init];
55 | if (self) {
56 |
57 | AudioFileStreamOpen((__bridge void *)(self), audioFileStreamPropertyListenerProc, audioFileStreamPacketsProc, kAudioFileMP3Type, &audioFileStreamID);
58 |
59 | }
60 | return self;
61 | }
62 |
63 | - (void)parseData:(NSData *)inData
64 | {
65 | AudioFileStreamParseBytes(audioFileStreamID, (UInt32)[inData length], [inData bytes], 0);
66 | }
67 |
68 | @synthesize delegate;
69 | @end
70 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // RemoteInput
4 | //
5 | // Created by StevenKuo on 2015/12/2.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // RemoteInput
4 | //
5 | // Created by StevenKuo on 2015/12/2.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import
11 | #import
12 |
13 | #import "SKAudioParser.h"
14 | #import "SKAudioBuffer.h"
15 | #import "SKAudioConverter.h"
16 |
17 | @interface ViewController ()
18 | {
19 | AUGraph audioGraph;
20 | AUNode mixNode;
21 | AudioUnit mixAudioUnit;
22 | AUNode remoteIONode;
23 | AudioUnit remoteIOAudioUnit;
24 |
25 | SKAudioParser *parser;
26 | SKAudioBuffer *buffer;
27 |
28 | SKAudioConverter *converter;
29 | IBOutlet UITextField *textFeild;
30 | IBOutlet UILabel *tip;
31 | }
32 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber;
33 | @end
34 |
35 |
36 | static void MyAudioUnitPropertyListenerProc(void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope,AudioUnitElement inElement);
37 |
38 | static OSStatus RenderCallback(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
39 |
40 | @implementation ViewController
41 |
42 | - (id)initWithCoder:(NSCoder *)aDecoder
43 | {
44 | self = [super initWithCoder:aDecoder];
45 | if (self) {
46 |
47 | parser = [[SKAudioParser alloc] init];
48 | parser.delegate = self;
49 |
50 | buffer = [[SKAudioBuffer alloc] init];
51 |
52 | OSStatus status = noErr;
53 | status = NewAUGraph(&audioGraph);
54 | status = AUGraphOpen(audioGraph);
55 |
56 | AudioComponentDescription outputUnitDescription = [self outputUnitDescription];
57 | status = AUGraphAddNode(audioGraph, &outputUnitDescription, &remoteIONode);
58 | status = AUGraphNodeInfo(audioGraph, remoteIONode, &outputUnitDescription, &remoteIOAudioUnit);
59 | UInt32 maxFPS = 4096;
60 | status = AudioUnitSetProperty(remoteIOAudioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0,&maxFPS, sizeof(maxFPS));
61 |
62 | AudioComponentDescription mixUnitDescription = [self mixUnitDescription];
63 | status = AUGraphAddNode(audioGraph, &mixUnitDescription, &mixNode);
64 | status = AUGraphNodeInfo(audioGraph, mixNode, &mixUnitDescription, &mixAudioUnit);
65 | status = AudioUnitSetProperty(mixAudioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0,&maxFPS, sizeof(maxFPS));
66 |
67 | status = AUGraphConnectNodeInput(audioGraph, mixNode, 0, remoteIONode, 0);
68 | status = AUGraphConnectNodeInput(audioGraph, remoteIONode, 1, mixNode, 1);
69 | status = AUGraphConnectNodeInput(audioGraph, mixNode, 1, remoteIONode, 0);
70 |
71 | AudioStreamBasicDescription destFormat = LinearPCMStreamDescription();
72 |
73 | UInt32 oneFlag = 1;
74 | UInt32 busOne = 1;
75 | status = AudioUnitSetProperty(remoteIOAudioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, busOne, &oneFlag, sizeof(oneFlag));
76 |
77 |
78 | status = AudioUnitSetProperty(remoteIOAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &destFormat, sizeof(destFormat));
79 |
80 | status = AudioUnitSetProperty(remoteIOAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &destFormat, sizeof(destFormat));
81 |
82 | status = AudioUnitSetProperty(mixAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &destFormat, sizeof(destFormat));
83 |
84 | status = AudioUnitSetProperty(mixAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &destFormat, sizeof(destFormat));
85 |
86 |
87 |
88 | status = AudioUnitSetParameter(mixAudioUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, 0, 0.3, 0);
89 |
90 |
91 | status = AudioUnitAddPropertyListener(remoteIOAudioUnit, kAudioOutputUnitProperty_IsRunning, MyAudioUnitPropertyListenerProc, (__bridge void *)(self));
92 |
93 | AURenderCallbackStruct callbackStruct;
94 | callbackStruct.inputProcRefCon = (__bridge void *)(self);
95 | callbackStruct.inputProc = RenderCallback;
96 | status = AUGraphSetNodeInputCallback(audioGraph, mixNode, 0, &callbackStruct);
97 |
98 | status = AUGraphInitialize(audioGraph);
99 |
100 | CAShow(audioGraph);
101 | AudioOutputUnitStop(remoteIOAudioUnit);
102 | }
103 | return self;
104 | }
105 |
106 | - (AudioComponentDescription)mixUnitDescription
107 | {
108 | AudioComponentDescription mixerUnitDescription;
109 | bzero(&mixerUnitDescription, sizeof(AudioComponentDescription));
110 | mixerUnitDescription.componentType = kAudioUnitType_Mixer;
111 | mixerUnitDescription.componentSubType = kAudioUnitSubType_MultiChannelMixer;
112 | mixerUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
113 | mixerUnitDescription.componentFlags = 0;
114 | mixerUnitDescription.componentFlagsMask = 0;
115 | return mixerUnitDescription;
116 | }
117 |
118 | - (AudioComponentDescription)outputUnitDescription
119 | {
120 | AudioComponentDescription outputUnitDescription;
121 | bzero(&outputUnitDescription, sizeof(AudioComponentDescription));
122 | outputUnitDescription.componentType = kAudioUnitType_Output;
123 | outputUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
124 | outputUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
125 | outputUnitDescription.componentFlags = 0;
126 | outputUnitDescription.componentFlagsMask = 0;
127 | return outputUnitDescription;
128 | }
129 |
130 | - (void)viewDidLoad {
131 | [super viewDidLoad];
132 | OSStatus aError = AUGraphStart(audioGraph);
133 | aError = AudioOutputUnitStart(remoteIOAudioUnit);
134 | }
135 |
136 | - (BOOL)textFieldShouldReturn:(UITextField *)textField {
137 | [textFeild resignFirstResponder];
138 | [textFeild setEnabled:NO];
139 | return YES;
140 | }
141 |
142 | - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
143 | {
144 | dispatch_async(dispatch_get_main_queue(), ^{
145 | tip.text = @"receiving data...";
146 | tip.textColor = UIColor.blackColor;
147 | });
148 | completionHandler(NSURLSessionResponseAllow);
149 | }
150 |
151 | - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
152 | {
153 | [parser parseData:data];
154 | }
155 |
156 | - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
157 | {
158 | dispatch_async(dispatch_get_main_queue(), ^{
159 | if (error) {
160 | tip.textColor = UIColor.redColor;
161 | tip.text = @"Fail";
162 | textFeild.text = @"";
163 | [textFeild setEnabled:YES];
164 | return;
165 | }
166 | tip.text = @"";
167 | });
168 | }
169 |
170 | - (void)textFieldDidEndEditing:(UITextField *)textField {
171 | NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
172 | NSURLSessionConfiguration *myConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
173 | NSURLSession *operationSession = [NSURLSession sessionWithConfiguration:myConfiguration delegate:(id)self delegateQueue:operationQueue];
174 |
175 | NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:textFeild.text]];
176 | NSURLSessionDataTask *task = [operationSession dataTaskWithRequest:request];
177 | [task resume];
178 | }
179 |
180 |
181 | - (void)audioStreamParser:(SKAudioParser *)inParser didObtainStreamDescription:(AudioStreamBasicDescription *)inDescription
182 | {
183 | NSLog(@"mSampleRate: %f", inDescription->mSampleRate);
184 | NSLog(@"mFormatID: %u", (unsigned int)inDescription->mFormatID);
185 | NSLog(@"mFormatFlags: %u", (unsigned int)inDescription->mFormatFlags);
186 | NSLog(@"mBytesPerPacket: %u", (unsigned int)inDescription->mBytesPerPacket);
187 | NSLog(@"mFramesPerPacket: %u", (unsigned int)inDescription->mFramesPerPacket);
188 | NSLog(@"mBytesPerFrame: %u", (unsigned int)inDescription->mBytesPerFrame);
189 | NSLog(@"mChannelsPerFrame: %u", (unsigned int)inDescription->mChannelsPerFrame);
190 | NSLog(@"mBitsPerChannel: %u", (unsigned int)inDescription->mBitsPerChannel);
191 | NSLog(@"mReserved: %u", (unsigned int)inDescription->mReserved);
192 |
193 | converter = [[SKAudioConverter alloc] initWithSourceFormat:inDescription];
194 | }
195 | - (void)audioStreamParser:(SKAudioParser *)inParser packetData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount
196 | {
197 | [buffer storePacketData:inBytes dataLength:inLength packetDescriptions:inPacketDescriptions packetsCount:inPacketsCount];
198 | }
199 |
200 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber
201 | {
202 | if (buffer.availablePacketCount < converter.packetsPerSecond * 4) {
203 | return -1;
204 | }
205 | return [converter requestNumberOfFrames:inNumberOfFrames ioData:inIoData busNumber:inBusNumber buffer:buffer];
206 | }
207 |
208 | void MyAudioUnitPropertyListenerProc(void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope,AudioUnitElement inElement)
209 | {
210 |
211 | }
212 |
213 | static OSStatus RenderCallback(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
214 | {
215 | ViewController *self = (__bridge ViewController *)userData;
216 |
217 | OSStatus status = [self requestNumberOfFrames:inNumberFrames ioData:ioData busNumber:inBusNumber];
218 |
219 | return status;
220 | }
221 |
222 | @end
223 |
--------------------------------------------------------------------------------
/AudioUnitSample/RemoteInput/RemoteInput/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // RemoteInput
4 | //
5 | // Created by StevenKuo on 2015/12/2.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevenKuo/AudioUnitSample/b50c8111600d283cbde02ce48f1ae36b3aa49f61/AudioUnitSample/SimplePlaying/.DS_Store
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9C10C3FD1BF34592001FE535 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C10C3FC1BF34592001FE535 /* main.m */; };
11 | 9C10C4001BF34592001FE535 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C10C3FF1BF34592001FE535 /* AppDelegate.m */; };
12 | 9C10C4031BF34592001FE535 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C10C4021BF34592001FE535 /* ViewController.m */; };
13 | 9C10C4061BF34592001FE535 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C10C4041BF34592001FE535 /* Main.storyboard */; };
14 | 9C10C4081BF34592001FE535 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9C10C4071BF34592001FE535 /* Assets.xcassets */; };
15 | 9C10C40B1BF34592001FE535 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C10C4091BF34592001FE535 /* LaunchScreen.storyboard */; };
16 | 9C10C4161BF347A7001FE535 /* SKAudioBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C10C4131BF347A7001FE535 /* SKAudioBuffer.m */; };
17 | 9C10C4171BF347A7001FE535 /* SKAudioParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C10C4151BF347A7001FE535 /* SKAudioParser.m */; };
18 | 9C10C41A1BF347E5001FE535 /* SKAudioConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C10C4191BF347E5001FE535 /* SKAudioConverter.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | 9C10C3F81BF34592001FE535 /* SimplePlaying.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimplePlaying.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | 9C10C3FC1BF34592001FE535 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
24 | 9C10C3FE1BF34592001FE535 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
25 | 9C10C3FF1BF34592001FE535 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
26 | 9C10C4011BF34592001FE535 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
27 | 9C10C4021BF34592001FE535 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
28 | 9C10C4051BF34592001FE535 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
29 | 9C10C4071BF34592001FE535 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
30 | 9C10C40A1BF34592001FE535 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
31 | 9C10C40C1BF34592001FE535 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
32 | 9C10C4121BF347A7001FE535 /* SKAudioBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKAudioBuffer.h; sourceTree = ""; };
33 | 9C10C4131BF347A7001FE535 /* SKAudioBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKAudioBuffer.m; sourceTree = ""; };
34 | 9C10C4141BF347A7001FE535 /* SKAudioParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKAudioParser.h; sourceTree = ""; };
35 | 9C10C4151BF347A7001FE535 /* SKAudioParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKAudioParser.m; sourceTree = ""; };
36 | 9C10C4181BF347E5001FE535 /* SKAudioConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKAudioConverter.h; sourceTree = ""; };
37 | 9C10C4191BF347E5001FE535 /* SKAudioConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKAudioConverter.m; sourceTree = ""; };
38 | /* End PBXFileReference section */
39 |
40 | /* Begin PBXFrameworksBuildPhase section */
41 | 9C10C3F51BF34592001FE535 /* Frameworks */ = {
42 | isa = PBXFrameworksBuildPhase;
43 | buildActionMask = 2147483647;
44 | files = (
45 | );
46 | runOnlyForDeploymentPostprocessing = 0;
47 | };
48 | /* End PBXFrameworksBuildPhase section */
49 |
50 | /* Begin PBXGroup section */
51 | 9C10C3EF1BF34592001FE535 = {
52 | isa = PBXGroup;
53 | children = (
54 | 9C10C3FA1BF34592001FE535 /* SimplePlaying */,
55 | 9C10C3F91BF34592001FE535 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | 9C10C3F91BF34592001FE535 /* Products */ = {
60 | isa = PBXGroup;
61 | children = (
62 | 9C10C3F81BF34592001FE535 /* SimplePlaying.app */,
63 | );
64 | name = Products;
65 | sourceTree = "";
66 | };
67 | 9C10C3FA1BF34592001FE535 /* SimplePlaying */ = {
68 | isa = PBXGroup;
69 | children = (
70 | 9C10C4181BF347E5001FE535 /* SKAudioConverter.h */,
71 | 9C10C4191BF347E5001FE535 /* SKAudioConverter.m */,
72 | 9C10C4121BF347A7001FE535 /* SKAudioBuffer.h */,
73 | 9C10C4131BF347A7001FE535 /* SKAudioBuffer.m */,
74 | 9C10C4141BF347A7001FE535 /* SKAudioParser.h */,
75 | 9C10C4151BF347A7001FE535 /* SKAudioParser.m */,
76 | 9C10C3FE1BF34592001FE535 /* AppDelegate.h */,
77 | 9C10C3FF1BF34592001FE535 /* AppDelegate.m */,
78 | 9C10C4011BF34592001FE535 /* ViewController.h */,
79 | 9C10C4021BF34592001FE535 /* ViewController.m */,
80 | 9C10C4041BF34592001FE535 /* Main.storyboard */,
81 | 9C10C4071BF34592001FE535 /* Assets.xcassets */,
82 | 9C10C4091BF34592001FE535 /* LaunchScreen.storyboard */,
83 | 9C10C40C1BF34592001FE535 /* Info.plist */,
84 | 9C10C3FB1BF34592001FE535 /* Supporting Files */,
85 | );
86 | path = SimplePlaying;
87 | sourceTree = "";
88 | };
89 | 9C10C3FB1BF34592001FE535 /* Supporting Files */ = {
90 | isa = PBXGroup;
91 | children = (
92 | 9C10C3FC1BF34592001FE535 /* main.m */,
93 | );
94 | name = "Supporting Files";
95 | sourceTree = "";
96 | };
97 | /* End PBXGroup section */
98 |
99 | /* Begin PBXNativeTarget section */
100 | 9C10C3F71BF34592001FE535 /* SimplePlaying */ = {
101 | isa = PBXNativeTarget;
102 | buildConfigurationList = 9C10C40F1BF34592001FE535 /* Build configuration list for PBXNativeTarget "SimplePlaying" */;
103 | buildPhases = (
104 | 9C10C3F41BF34592001FE535 /* Sources */,
105 | 9C10C3F51BF34592001FE535 /* Frameworks */,
106 | 9C10C3F61BF34592001FE535 /* Resources */,
107 | );
108 | buildRules = (
109 | );
110 | dependencies = (
111 | );
112 | name = SimplePlaying;
113 | productName = SimplePlaying;
114 | productReference = 9C10C3F81BF34592001FE535 /* SimplePlaying.app */;
115 | productType = "com.apple.product-type.application";
116 | };
117 | /* End PBXNativeTarget section */
118 |
119 | /* Begin PBXProject section */
120 | 9C10C3F01BF34592001FE535 /* Project object */ = {
121 | isa = PBXProject;
122 | attributes = {
123 | LastUpgradeCheck = 0710;
124 | ORGANIZATIONNAME = StevenKuo;
125 | TargetAttributes = {
126 | 9C10C3F71BF34592001FE535 = {
127 | CreatedOnToolsVersion = 7.1;
128 | };
129 | };
130 | };
131 | buildConfigurationList = 9C10C3F31BF34592001FE535 /* Build configuration list for PBXProject "SimplePlaying" */;
132 | compatibilityVersion = "Xcode 3.2";
133 | developmentRegion = English;
134 | hasScannedForEncodings = 0;
135 | knownRegions = (
136 | en,
137 | Base,
138 | );
139 | mainGroup = 9C10C3EF1BF34592001FE535;
140 | productRefGroup = 9C10C3F91BF34592001FE535 /* Products */;
141 | projectDirPath = "";
142 | projectRoot = "";
143 | targets = (
144 | 9C10C3F71BF34592001FE535 /* SimplePlaying */,
145 | );
146 | };
147 | /* End PBXProject section */
148 |
149 | /* Begin PBXResourcesBuildPhase section */
150 | 9C10C3F61BF34592001FE535 /* Resources */ = {
151 | isa = PBXResourcesBuildPhase;
152 | buildActionMask = 2147483647;
153 | files = (
154 | 9C10C40B1BF34592001FE535 /* LaunchScreen.storyboard in Resources */,
155 | 9C10C4081BF34592001FE535 /* Assets.xcassets in Resources */,
156 | 9C10C4061BF34592001FE535 /* Main.storyboard in Resources */,
157 | );
158 | runOnlyForDeploymentPostprocessing = 0;
159 | };
160 | /* End PBXResourcesBuildPhase section */
161 |
162 | /* Begin PBXSourcesBuildPhase section */
163 | 9C10C3F41BF34592001FE535 /* Sources */ = {
164 | isa = PBXSourcesBuildPhase;
165 | buildActionMask = 2147483647;
166 | files = (
167 | 9C10C4161BF347A7001FE535 /* SKAudioBuffer.m in Sources */,
168 | 9C10C41A1BF347E5001FE535 /* SKAudioConverter.m in Sources */,
169 | 9C10C4031BF34592001FE535 /* ViewController.m in Sources */,
170 | 9C10C4001BF34592001FE535 /* AppDelegate.m in Sources */,
171 | 9C10C4171BF347A7001FE535 /* SKAudioParser.m in Sources */,
172 | 9C10C3FD1BF34592001FE535 /* main.m in Sources */,
173 | );
174 | runOnlyForDeploymentPostprocessing = 0;
175 | };
176 | /* End PBXSourcesBuildPhase section */
177 |
178 | /* Begin PBXVariantGroup section */
179 | 9C10C4041BF34592001FE535 /* Main.storyboard */ = {
180 | isa = PBXVariantGroup;
181 | children = (
182 | 9C10C4051BF34592001FE535 /* Base */,
183 | );
184 | name = Main.storyboard;
185 | sourceTree = "";
186 | };
187 | 9C10C4091BF34592001FE535 /* LaunchScreen.storyboard */ = {
188 | isa = PBXVariantGroup;
189 | children = (
190 | 9C10C40A1BF34592001FE535 /* Base */,
191 | );
192 | name = LaunchScreen.storyboard;
193 | sourceTree = "";
194 | };
195 | /* End PBXVariantGroup section */
196 |
197 | /* Begin XCBuildConfiguration section */
198 | 9C10C40D1BF34592001FE535 /* Debug */ = {
199 | isa = XCBuildConfiguration;
200 | buildSettings = {
201 | ALWAYS_SEARCH_USER_PATHS = NO;
202 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
203 | CLANG_CXX_LIBRARY = "libc++";
204 | CLANG_ENABLE_MODULES = YES;
205 | CLANG_ENABLE_OBJC_ARC = YES;
206 | CLANG_WARN_BOOL_CONVERSION = YES;
207 | CLANG_WARN_CONSTANT_CONVERSION = YES;
208 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
209 | CLANG_WARN_EMPTY_BODY = YES;
210 | CLANG_WARN_ENUM_CONVERSION = YES;
211 | CLANG_WARN_INT_CONVERSION = YES;
212 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
213 | CLANG_WARN_UNREACHABLE_CODE = YES;
214 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
215 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
216 | COPY_PHASE_STRIP = NO;
217 | DEBUG_INFORMATION_FORMAT = dwarf;
218 | ENABLE_STRICT_OBJC_MSGSEND = YES;
219 | ENABLE_TESTABILITY = YES;
220 | GCC_C_LANGUAGE_STANDARD = gnu99;
221 | GCC_DYNAMIC_NO_PIC = NO;
222 | GCC_NO_COMMON_BLOCKS = YES;
223 | GCC_OPTIMIZATION_LEVEL = 0;
224 | GCC_PREPROCESSOR_DEFINITIONS = (
225 | "DEBUG=1",
226 | "$(inherited)",
227 | );
228 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
229 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
230 | GCC_WARN_UNDECLARED_SELECTOR = YES;
231 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
232 | GCC_WARN_UNUSED_FUNCTION = YES;
233 | GCC_WARN_UNUSED_VARIABLE = YES;
234 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
235 | MTL_ENABLE_DEBUG_INFO = YES;
236 | ONLY_ACTIVE_ARCH = YES;
237 | SDKROOT = iphoneos;
238 | TARGETED_DEVICE_FAMILY = "1,2";
239 | };
240 | name = Debug;
241 | };
242 | 9C10C40E1BF34592001FE535 /* Release */ = {
243 | isa = XCBuildConfiguration;
244 | buildSettings = {
245 | ALWAYS_SEARCH_USER_PATHS = NO;
246 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
247 | CLANG_CXX_LIBRARY = "libc++";
248 | CLANG_ENABLE_MODULES = YES;
249 | CLANG_ENABLE_OBJC_ARC = YES;
250 | CLANG_WARN_BOOL_CONVERSION = YES;
251 | CLANG_WARN_CONSTANT_CONVERSION = YES;
252 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
253 | CLANG_WARN_EMPTY_BODY = YES;
254 | CLANG_WARN_ENUM_CONVERSION = YES;
255 | CLANG_WARN_INT_CONVERSION = YES;
256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 | CLANG_WARN_UNREACHABLE_CODE = YES;
258 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
259 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
260 | COPY_PHASE_STRIP = NO;
261 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
262 | ENABLE_NS_ASSERTIONS = NO;
263 | ENABLE_STRICT_OBJC_MSGSEND = YES;
264 | GCC_C_LANGUAGE_STANDARD = gnu99;
265 | GCC_NO_COMMON_BLOCKS = YES;
266 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
267 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
268 | GCC_WARN_UNDECLARED_SELECTOR = YES;
269 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
270 | GCC_WARN_UNUSED_FUNCTION = YES;
271 | GCC_WARN_UNUSED_VARIABLE = YES;
272 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
273 | MTL_ENABLE_DEBUG_INFO = NO;
274 | SDKROOT = iphoneos;
275 | TARGETED_DEVICE_FAMILY = "1,2";
276 | VALIDATE_PRODUCT = YES;
277 | };
278 | name = Release;
279 | };
280 | 9C10C4101BF34592001FE535 /* Debug */ = {
281 | isa = XCBuildConfiguration;
282 | buildSettings = {
283 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
284 | INFOPLIST_FILE = SimplePlaying/Info.plist;
285 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
286 | PRODUCT_BUNDLE_IDENTIFIER = SK.SimplePlaying;
287 | PRODUCT_NAME = "$(TARGET_NAME)";
288 | };
289 | name = Debug;
290 | };
291 | 9C10C4111BF34592001FE535 /* Release */ = {
292 | isa = XCBuildConfiguration;
293 | buildSettings = {
294 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
295 | INFOPLIST_FILE = SimplePlaying/Info.plist;
296 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
297 | PRODUCT_BUNDLE_IDENTIFIER = SK.SimplePlaying;
298 | PRODUCT_NAME = "$(TARGET_NAME)";
299 | };
300 | name = Release;
301 | };
302 | /* End XCBuildConfiguration section */
303 |
304 | /* Begin XCConfigurationList section */
305 | 9C10C3F31BF34592001FE535 /* Build configuration list for PBXProject "SimplePlaying" */ = {
306 | isa = XCConfigurationList;
307 | buildConfigurations = (
308 | 9C10C40D1BF34592001FE535 /* Debug */,
309 | 9C10C40E1BF34592001FE535 /* Release */,
310 | );
311 | defaultConfigurationIsVisible = 0;
312 | defaultConfigurationName = Release;
313 | };
314 | 9C10C40F1BF34592001FE535 /* Build configuration list for PBXNativeTarget "SimplePlaying" */ = {
315 | isa = XCConfigurationList;
316 | buildConfigurations = (
317 | 9C10C4101BF34592001FE535 /* Debug */,
318 | 9C10C4111BF34592001FE535 /* Release */,
319 | );
320 | defaultConfigurationIsVisible = 0;
321 | };
322 | /* End XCConfigurationList section */
323 | };
324 | rootObject = 9C10C3F01BF34592001FE535 /* Project object */;
325 | }
326 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
40 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSAppTransportSecurity
6 |
7 | NSAllowsArbitraryLoads
8 |
9 |
10 | CFBundleDevelopmentRegion
11 | en
12 | CFBundleExecutable
13 | $(EXECUTABLE_NAME)
14 | CFBundleIdentifier
15 | $(PRODUCT_BUNDLE_IDENTIFIER)
16 | CFBundleInfoDictionaryVersion
17 | 6.0
18 | CFBundleName
19 | $(PRODUCT_NAME)
20 | CFBundlePackageType
21 | APPL
22 | CFBundleShortVersionString
23 | 1.0
24 | CFBundleSignature
25 | ????
26 | CFBundleVersion
27 | 1
28 | LSRequiresIPhoneOS
29 |
30 | UILaunchStoryboardName
31 | LaunchScreen
32 | UIMainStoryboardFile
33 | Main
34 | UIRequiredDeviceCapabilities
35 |
36 | armv7
37 |
38 | UISupportedInterfaceOrientations
39 |
40 | UIInterfaceOrientationPortrait
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/SKAudioBuffer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioBuffer.h
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | typedef struct {
13 | AudioStreamPacketDescription packetDescription;
14 | void *data;
15 | } AudioPacketInfo;
16 |
17 | @class SKAudioBuffer;
18 |
19 | @protocol SKAudioBufferDelegate
20 |
21 | - (AudioStreamBasicDescription)usedAudioStreamBasicDescription;
22 | - (void)audioBufferDidBeginReadPacket:(SKAudioBuffer *)inBuffer;
23 | @end
24 |
25 | @interface SKAudioBuffer : NSObject
26 | {
27 | __weak id delegate;
28 |
29 | AudioPacketInfo *packets;
30 | size_t packetWriteIndex;
31 | size_t packetReadIndex;
32 | size_t packetCount;
33 |
34 | NSMutableData *audioData;
35 | NSMutableData *packetDescData;
36 | NSUInteger packetReadHead;
37 | NSUInteger readPacketIndex;
38 | }
39 |
40 |
41 | - (void)storePacketData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount;
42 | - (void)movePacketReadIndex;
43 |
44 | @property (readonly, nonatomic) size_t availablePacketCount;
45 | @property (weak, nonatomic) id delegate;
46 | @property (readonly, nonatomic) AudioPacketInfo currentPacketInfo;
47 | @end
48 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/SKAudioBuffer.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioBuffer.m
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import "SKAudioBuffer.h"
10 |
11 | @implementation SKAudioBuffer
12 |
13 | - (id)init
14 | {
15 | self = [super init];
16 | if (self) {
17 |
18 | packetCount = 2048;
19 | packets = (AudioPacketInfo *)calloc(packetCount, sizeof(AudioPacketInfo));
20 |
21 | audioData = [[NSMutableData alloc] init];
22 | packetDescData = [[NSMutableData alloc] init];
23 | }
24 | return self;
25 | }
26 |
27 |
28 | - (void)storePacketData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount
29 | {
30 | // for (NSUInteger packetIndex = 0; packetIndex < inPacketsCount ; packetIndex ++) {
31 | // inPacketDescriptions[packetIndex].mStartOffset += audioData.length;
32 | // }
33 | //
34 | // @synchronized (self) {
35 | // [audioData appendBytes:inBytes length:inLength];
36 | // [packetDescData appendBytes:inPacketDescriptions length:sizeof(AudioStreamPacketDescription) * inPacketsCount];
37 | // availablePacketCount += inPacketsCount;
38 | // }
39 |
40 | @synchronized (self) {
41 |
42 | for (size_t index = 0; index < inPacketsCount; index ++) {
43 |
44 | if (packetWriteIndex >= packetCount) {
45 | size_t oldSize = packetCount * sizeof(AudioPacketInfo);
46 | packetCount = packetCount * 2;
47 | packets = (AudioPacketInfo *)realloc(packets, packetCount * sizeof(AudioPacketInfo));
48 | bzero((void *)packets + oldSize, oldSize);
49 | }
50 | AudioStreamPacketDescription emptyDescription;
51 |
52 | if (!inPacketDescriptions) {
53 | emptyDescription.mStartOffset = index;
54 | emptyDescription.mDataByteSize = 1;
55 | emptyDescription.mVariableFramesInPacket = 0;
56 | }
57 |
58 | AudioStreamPacketDescription *currentDescription = inPacketDescriptions ? &(inPacketDescriptions[index]) : &emptyDescription;
59 |
60 | AudioPacketInfo *nextInfo = &packets[packetWriteIndex];
61 | if (nextInfo->data) {
62 | free(nextInfo->data);
63 | nextInfo->data = NULL;
64 | }
65 | nextInfo->data = malloc(currentDescription->mDataByteSize);
66 | NSAssert(nextInfo->data, @"Must allocate memory for current packet");
67 | memcpy(nextInfo->data, inBytes + currentDescription->mStartOffset, currentDescription->mDataByteSize);
68 | memcpy(&nextInfo->packetDescription, currentDescription, sizeof(AudioStreamPacketDescription));
69 |
70 | packetWriteIndex++;
71 |
72 | _availablePacketCount++;
73 | }
74 | }
75 | }
76 |
77 | - (void)setPacketReadIndex:(size_t)inNewIndex
78 | {
79 | size_t max = _availablePacketCount;
80 |
81 | if (inNewIndex > max) {
82 | packetReadIndex = max;
83 | return;
84 | }
85 |
86 | if (inNewIndex < packetWriteIndex) {
87 | packetReadIndex = inNewIndex;
88 | }
89 | else {
90 | packetReadIndex = packetWriteIndex;
91 | }
92 | }
93 |
94 | - (void)movePacketReadIndex
95 | {
96 | [self setPacketReadIndex:packetReadIndex + 1];
97 | }
98 |
99 | - (AudioPacketInfo)currentPacketInfo
100 | {
101 | // @synchronized (self) {
102 | // if (readPacketIndex >= availablePacketCount) {
103 | // inCallback(nil, 0, nil, YES);
104 | // return;
105 | // }
106 | // if (readPacketIndex == 0) {
107 | // [delegate audioBufferDidBeginReadPacket:self];
108 | // }
109 | //
110 | // AudioStreamPacketDescription* packetDescriptions = (AudioStreamPacketDescription* )packetDescData.bytes;
111 | //
112 | // AudioPacketInfo *packet = (AudioPacketInfo *)calloc(1, sizeof(AudioPacketInfo));
113 | // packet->data = malloc(packetDescriptions[readPacketIndex].mDataByteSize);
114 | // memcpy(packet->data, audioData.bytes + packetDescriptions[readPacketIndex].mStartOffset, packetDescriptions[readPacketIndex].mDataByteSize);
115 | // memcpy(&packet->packetDescription, &packetDescriptions[readPacketIndex], sizeof(AudioStreamPacketDescription));
116 | //
117 | // readPacketIndex ++;
118 | //
119 | // return *packet;
120 | // }
121 | return packets[packetReadIndex];
122 | }
123 |
124 | @synthesize delegate;
125 | @synthesize currentPacketInfo;
126 | @end
127 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/SKAudioConverter.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioConverter.h
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "SKAudioBuffer.h"
12 |
13 | @interface SKAudioConverter : NSObject
14 | {
15 | AudioStreamBasicDescription audioStreamDescription;
16 | AudioStreamBasicDescription destFormat;
17 | AudioConverterRef converter;
18 | AudioBufferList *renderBufferList;
19 | UInt32 renderBufferSize;
20 | }
21 |
22 | AudioStreamBasicDescription LinearPCMStreamDescription();
23 |
24 | - (instancetype)initWithSourceFormat:(AudioStreamBasicDescription *)sourceFormat;
25 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber buffer:(SKAudioBuffer *)inBuffer;
26 |
27 | - (void)_fillBufferlist:(AudioBufferList *)ioData withBuffer:(SKAudioBuffer *)buffer packetDescription:(AudioStreamPacketDescription** )outDataPacketDescription;
28 | @property (readonly, nonatomic) double packetsPerSecond;
29 | @end
30 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/SKAudioConverter.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioConverter.m
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "SKAudioConverter.h"
10 |
11 | static OSStatus AudioConverterFiller(AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData);
12 |
13 | OSStatus AudioConverterFiller (AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData)
14 | {
15 | NSArray *args = (__bridge NSArray *)inUserData;
16 | SKAudioConverter *self = args[0];
17 | SKAudioBuffer *buffer = args[1];
18 | // *ioNumberDataPackets = 1;
19 | [self _fillBufferlist:ioData withBuffer:buffer packetDescription:outDataPacketDescription];
20 | return noErr;
21 | }
22 |
23 | AudioStreamBasicDescription LinearPCMStreamDescription()
24 | {
25 | AudioStreamBasicDescription destFormat;
26 | bzero(&destFormat, sizeof(AudioStreamBasicDescription));
27 | destFormat.mSampleRate = 44100.0;
28 | destFormat.mFormatID = kAudioFormatLinearPCM;
29 | destFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
30 |
31 | destFormat.mFramesPerPacket = 1;
32 | destFormat.mBytesPerPacket = 4;
33 | destFormat.mBytesPerFrame = 4;
34 | destFormat.mChannelsPerFrame = 2;
35 | destFormat.mBitsPerChannel = 16;
36 | destFormat.mReserved = 0;
37 | return destFormat;
38 | }
39 |
40 | @implementation SKAudioConverter
41 |
42 | - (instancetype)initWithSourceFormat:(AudioStreamBasicDescription *)sourceFormat
43 | {
44 | self = [super init];
45 | if (self) {
46 | audioStreamDescription = *sourceFormat;
47 | destFormat = LinearPCMStreamDescription();
48 | AudioConverterNew(&audioStreamDescription, &destFormat, &converter);
49 |
50 | UInt32 packetSize = 44100 * 4;
51 | renderBufferSize = packetSize;
52 | renderBufferList = (AudioBufferList *)calloc(1, sizeof(UInt32) + sizeof(AudioBuffer));
53 | renderBufferList->mNumberBuffers = 1;
54 | renderBufferList->mBuffers[0].mNumberChannels = 2;
55 | renderBufferList->mBuffers[0].mDataByteSize = packetSize;
56 | renderBufferList->mBuffers[0].mData = calloc(1, packetSize);
57 | }
58 | return self;
59 | }
60 |
61 | - (void)_fillBufferlist:(AudioBufferList *)ioData withBuffer:(SKAudioBuffer *)buffer packetDescription:(AudioStreamPacketDescription** )outDataPacketDescription
62 | {
63 | static AudioStreamPacketDescription aspdesc;
64 |
65 | AudioPacketInfo currentPacketInfo = buffer.currentPacketInfo;
66 |
67 | void *data = currentPacketInfo.data;
68 | UInt32 length = (UInt32)currentPacketInfo.packetDescription.mDataByteSize;
69 | ioData->mBuffers[0].mData = data;
70 | ioData->mBuffers[0].mDataByteSize = length;
71 | ioData->mNumberBuffers = 1;
72 |
73 | *outDataPacketDescription = &aspdesc;
74 | aspdesc.mDataByteSize = length;
75 | aspdesc.mStartOffset = 0;
76 | aspdesc.mVariableFramesInPacket = 1;
77 |
78 | [buffer movePacketReadIndex];
79 | }
80 |
81 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber buffer:(SKAudioBuffer *)inBuffer
82 | {
83 | UInt32 packetSize = inNumberOfFrames;
84 | NSArray *args = @[self, inBuffer];
85 | OSStatus status = noErr;
86 |
87 | status = AudioConverterFillComplexBuffer(converter, AudioConverterFiller, (__bridge void *)(args), &packetSize, renderBufferList, NULL);
88 |
89 | if (noErr == status && packetSize) {
90 | inIoData->mNumberBuffers = 1;
91 | inIoData->mBuffers[0].mNumberChannels = 2;
92 | inIoData->mBuffers[0].mDataByteSize = renderBufferList->mBuffers[0].mDataByteSize;
93 | inIoData->mBuffers[0].mData = renderBufferList->mBuffers[0].mData;
94 | status = noErr;
95 | }
96 | return status;
97 | }
98 |
99 | - (double)packetsPerSecond
100 | {
101 | if (!(audioStreamDescription.mFramesPerPacket > 0)) {
102 | return 0;
103 | }
104 | return audioStreamDescription.mSampleRate / audioStreamDescription.mFramesPerPacket;
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/SKAudioParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioParser.h
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class SKAudioParser;
13 |
14 | @protocol SKAudioParserDelegate
15 |
16 | - (void)audioStreamParser:(SKAudioParser *)inParser didObtainStreamDescription:(AudioStreamBasicDescription *)inDescription;
17 | - (void)audioStreamParser:(SKAudioParser *)inParser packetData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount;
18 |
19 | @end
20 |
21 | @interface SKAudioParser : NSObject
22 | {
23 | AudioFileStreamID audioFileStreamID;
24 | __weak id delegate;
25 | }
26 |
27 | - (void)parseData:(NSData *)inData;
28 |
29 | @property (weak, nonatomic) id delegate;
30 | @end
31 |
32 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/SKAudioParser.m:
--------------------------------------------------------------------------------
1 | //
2 | // SKAudioParser.m
3 | // SKAudioQueue
4 | //
5 | // Created by steven on 2015/1/22.
6 | // Copyright (c) 2015年 KKBOX. All rights reserved.
7 | //
8 |
9 | #import "SKAudioParser.h"
10 |
11 | @implementation SKAudioParser
12 |
13 |
14 | void audioFileStreamPropertyListenerProc(void *inClientData, AudioFileStreamID inAudioFileStream, AudioFileStreamPropertyID inPropertyID, UInt32 *ioFlags)
15 | {
16 | /*
17 | kAudioFileStreamProperty_ReadyToProducePackets = 'redy',
18 | kAudioFileStreamProperty_FileFormat = 'ffmt',
19 | kAudioFileStreamProperty_DataFormat = 'dfmt',
20 | kAudioFileStreamProperty_FormatList = 'flst',
21 | kAudioFileStreamProperty_MagicCookieData = 'mgic',
22 | kAudioFileStreamProperty_AudioDataByteCount = 'bcnt',
23 | kAudioFileStreamProperty_AudioDataPacketCount = 'pcnt',
24 | kAudioFileStreamProperty_MaximumPacketSize = 'psze',
25 | kAudioFileStreamProperty_DataOffset = 'doff',
26 | kAudioFileStreamProperty_ChannelLayout = 'cmap',
27 | kAudioFileStreamProperty_PacketToFrame = 'pkfr',
28 | kAudioFileStreamProperty_FrameToPacket = 'frpk',
29 | kAudioFileStreamProperty_PacketToByte = 'pkby',
30 | kAudioFileStreamProperty_ByteToPacket = 'bypk',
31 | kAudioFileStreamProperty_PacketTableInfo = 'pnfo',
32 | kAudioFileStreamProperty_PacketSizeUpperBound = 'pkub',
33 | kAudioFileStreamProperty_AverageBytesPerPacket = 'abpp',
34 | kAudioFileStreamProperty_BitRate = 'brat',
35 | kAudioFileStreamProperty_InfoDictionary = 'info'
36 | */
37 | if (inPropertyID == 'dfmt') {
38 | AudioStreamBasicDescription description;
39 | UInt32 descriptionSize = sizeof(description);
40 | AudioFileStreamGetProperty(inAudioFileStream, inPropertyID, &descriptionSize, &description);
41 | [((__bridge SKAudioParser *)inClientData).delegate audioStreamParser:(__bridge SKAudioParser *)inClientData didObtainStreamDescription:&description];
42 | }
43 | }
44 |
45 |
46 | void audioFileStreamPacketsProc(void *inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void *inInputData, AudioStreamPacketDescription *inPacketDescriptions)
47 | {
48 | [((__bridge SKAudioParser *)inClientData).delegate audioStreamParser:((__bridge SKAudioParser *)inClientData) packetData:inInputData dataLength:inNumberBytes packetDescriptions:inPacketDescriptions packetsCount:inNumberPackets];
49 |
50 | }
51 |
52 | - (id)init
53 | {
54 | self = [super init];
55 | if (self) {
56 |
57 | AudioFileStreamOpen((__bridge void *)(self), audioFileStreamPropertyListenerProc, audioFileStreamPacketsProc, kAudioFileMP3Type, &audioFileStreamID);
58 |
59 | }
60 | return self;
61 | }
62 |
63 | - (void)parseData:(NSData *)inData
64 | {
65 | AudioFileStreamParseBytes(audioFileStreamID, (UInt32)[inData length], [inData bytes], 0);
66 | }
67 |
68 | @synthesize delegate;
69 | @end
70 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import
11 | #import
12 | #import "SKAudioParser.h"
13 | #import "SKAudioBuffer.h"
14 | #import "SKAudioConverter.h"
15 |
16 | @interface ViewController ()
17 | {
18 | AUGraph audioGraph;
19 | AUNode node;
20 | AudioUnit audioUnit;
21 |
22 | SKAudioParser *parser;
23 | SKAudioBuffer *buffer;
24 |
25 | SKAudioConverter *converter;
26 | IBOutlet UITextField *textFeild;
27 | IBOutlet UILabel *tip;
28 | }
29 | @end
30 |
31 | static void MyAudioUnitPropertyListenerProc(void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope,AudioUnitElement inElement);
32 |
33 | static OSStatus RenderCallback(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
34 |
35 | @implementation ViewController
36 |
37 | - (id)initWithCoder:(NSCoder *)aDecoder
38 | {
39 | self = [super initWithCoder:aDecoder];
40 | if (self) {
41 |
42 | parser = [[SKAudioParser alloc] init];
43 | parser.delegate = self;
44 |
45 | buffer = [[SKAudioBuffer alloc] init];
46 |
47 | OSStatus status = noErr;
48 | status = NewAUGraph(&audioGraph);
49 | status = AUGraphOpen(audioGraph);
50 |
51 | AudioComponentDescription unitDescription = [self unitDescription];
52 | status = AUGraphAddNode(audioGraph, &unitDescription, &node);
53 | status = AUGraphNodeInfo(audioGraph, node, &unitDescription, &audioUnit);
54 | UInt32 maxFPS = 4096;
55 | status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0,&maxFPS, sizeof(maxFPS));
56 |
57 | AudioStreamBasicDescription destFormat = LinearPCMStreamDescription();
58 |
59 | status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &destFormat, sizeof(destFormat));
60 |
61 | status = AudioUnitAddPropertyListener(audioUnit, kAudioOutputUnitProperty_IsRunning, MyAudioUnitPropertyListenerProc, (__bridge void *)(self));
62 |
63 | AURenderCallbackStruct callbackStruct;
64 | callbackStruct.inputProcRefCon = (__bridge void *)(self);
65 | callbackStruct.inputProc = RenderCallback;
66 |
67 | status = AUGraphSetNodeInputCallback(audioGraph, node, 0, &callbackStruct);
68 | status = AUGraphInitialize(audioGraph);
69 | AudioOutputUnitStop(audioUnit);
70 |
71 | }
72 | return self;
73 | }
74 |
75 | - (AudioComponentDescription)unitDescription
76 | {
77 | AudioComponentDescription outputUnitDescription;
78 | bzero(&outputUnitDescription, sizeof(AudioComponentDescription));
79 | outputUnitDescription.componentType = kAudioUnitType_Output;
80 | outputUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
81 | outputUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
82 | outputUnitDescription.componentFlags = 0;
83 | outputUnitDescription.componentFlagsMask = 0;
84 | return outputUnitDescription;
85 | }
86 |
87 | - (void)viewDidLoad {
88 | [super viewDidLoad];
89 | OSStatus aError = AUGraphStart(audioGraph);
90 | aError = AudioOutputUnitStart(audioUnit);
91 | }
92 |
93 | - (void)textFieldDidEndEditing:(UITextField *)textField {
94 | NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
95 | NSURLSessionConfiguration *myConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
96 | NSURLSession *operationSession = [NSURLSession sessionWithConfiguration:myConfiguration delegate:(id)self delegateQueue:operationQueue];
97 |
98 | NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:textFeild.text]];
99 | NSURLSessionDataTask *task = [operationSession dataTaskWithRequest:request];
100 | [task resume];
101 | }
102 |
103 | - (BOOL)textFieldShouldReturn:(UITextField *)textField {
104 | [textFeild resignFirstResponder];
105 | [textFeild setEnabled:NO];
106 | return YES;
107 | }
108 |
109 | - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
110 | {
111 | dispatch_async(dispatch_get_main_queue(), ^{
112 | tip.text = @"receiving data...";
113 | tip.textColor = UIColor.blackColor;
114 | });
115 | completionHandler(NSURLSessionResponseAllow);
116 | }
117 |
118 | - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
119 | {
120 | [parser parseData:data];
121 | }
122 |
123 | - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
124 | {
125 | dispatch_async(dispatch_get_main_queue(), ^{
126 | if (error) {
127 | tip.textColor = UIColor.redColor;
128 | tip.text = @"Fail";
129 | textFeild.text = @"";
130 | [textFeild setEnabled:YES];
131 | return;
132 | }
133 | tip.text = @"";
134 | });
135 | }
136 |
137 | - (void)audioStreamParser:(SKAudioParser *)inParser didObtainStreamDescription:(AudioStreamBasicDescription *)inDescription
138 | {
139 | NSLog(@"mSampleRate: %f", inDescription->mSampleRate);
140 | NSLog(@"mFormatID: %u", (unsigned int)inDescription->mFormatID);
141 | NSLog(@"mFormatFlags: %u", (unsigned int)inDescription->mFormatFlags);
142 | NSLog(@"mBytesPerPacket: %u", (unsigned int)inDescription->mBytesPerPacket);
143 | NSLog(@"mFramesPerPacket: %u", (unsigned int)inDescription->mFramesPerPacket);
144 | NSLog(@"mBytesPerFrame: %u", (unsigned int)inDescription->mBytesPerFrame);
145 | NSLog(@"mChannelsPerFrame: %u", (unsigned int)inDescription->mChannelsPerFrame);
146 | NSLog(@"mBitsPerChannel: %u", (unsigned int)inDescription->mBitsPerChannel);
147 | NSLog(@"mReserved: %u", (unsigned int)inDescription->mReserved);
148 |
149 | converter = [[SKAudioConverter alloc] initWithSourceFormat:inDescription];
150 |
151 | }
152 | - (void)audioStreamParser:(SKAudioParser *)inParser packetData:(const void * )inBytes dataLength:(UInt32)inLength packetDescriptions:(AudioStreamPacketDescription* )inPacketDescriptions packetsCount:(UInt32)inPacketsCount
153 | {
154 | [buffer storePacketData:inBytes dataLength:inLength packetDescriptions:inPacketDescriptions packetsCount:inPacketsCount];
155 | }
156 |
157 | - (OSStatus)requestNumberOfFrames:(UInt32)inNumberOfFrames ioData:(AudioBufferList *)inIoData busNumber:(UInt32)inBusNumber
158 | {
159 | if (buffer.availablePacketCount < converter.packetsPerSecond * 4) {
160 | return -1;
161 | }
162 | OSStatus status = [converter requestNumberOfFrames:inNumberOfFrames ioData:inIoData busNumber:inBusNumber buffer:buffer];
163 | /* remove vocal
164 | UInt16 *data = inIoData->mBuffers[0].mData;
165 | for (int i = 0; i < inIoData->mBuffers[0].mDataByteSize; i += 2) {
166 | UInt16 left = data[i];
167 | UInt16 right = data[i + 1];
168 | UInt16 new = left - right;
169 | data[i] = new;
170 | data[i+1] = new;
171 |
172 | }
173 | */
174 | return status;
175 | }
176 |
177 | void MyAudioUnitPropertyListenerProc(void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope,AudioUnitElement inElement)
178 | {
179 |
180 | }
181 |
182 | static OSStatus RenderCallback(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
183 | {
184 | ViewController *self = (__bridge ViewController *)userData;
185 |
186 | OSStatus status = [self requestNumberOfFrames:inNumberFrames ioData:ioData busNumber:inBusNumber];
187 |
188 | return status;
189 | }
190 |
191 | @end
192 |
--------------------------------------------------------------------------------
/AudioUnitSample/SimplePlaying/SimplePlaying/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SimplePlaying
4 | //
5 | // Created by StevenKuo on 2015/11/11.
6 | // Copyright © 2015年 StevenKuo. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AudioUnitSample
2 |
3 | ## SimplePlaying
4 | Uses remoteIO audioUnit to play streaming audio.
5 |
6 | ## RemoteIO
7 | Connects remoteIO unit and mix unit to fetch voice by microphone and playing streaming audio.
8 |
9 | ## MixPlaying
10 | Connects remoteIO unit and mix unit to play streaming audio from two resources.
11 |
--------------------------------------------------------------------------------