Skip to content

Commit 082e872

Browse files
committed
Update AudioKit. Add missing file.
1 parent b08834c commit 082e872

File tree

2 files changed

+169
-1
lines changed

2 files changed

+169
-1
lines changed

Package.resolved

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// Copyright AudioKit. All Rights Reserved. Revision History at http://github.com/AudioKit/AudioKit/
2+
3+
import AVFoundation
4+
import CAudioKit
5+
import AudioKit
6+
7+
/// This is a phase locked vocoder. It has the ability to play back an audio
8+
/// file loaded into an ftable like a sampler would. Unlike a typical sampler,
9+
/// mincer allows time and pitch to be controlled separately.
10+
///
11+
public class PhaseLockedVocoder: Node {
12+
13+
/// Connected nodes
14+
public var connections: [Node] { [] }
15+
16+
/// Underlying AVAudioNode
17+
public var avAudioNode = instantiate(instrument: "minc")
18+
19+
/// Specification for position
20+
public static let positionDef = NodeParameterDef(
21+
identifier: "position",
22+
name: "Position in time. When non-changing it will do a spectral freeze of a the current point in time.",
23+
address: akGetParameterAddress("PhaseLockedVocoderParameterPosition"),
24+
defaultValue: 0,
25+
range: 0 ... 100_000,
26+
unit: .generic)
27+
28+
/// Position in time. When non-changing it will do a spectral freeze of a the current point in time.
29+
@Parameter(positionDef) public var position: AUValue
30+
31+
/// Specification for amplitude
32+
public static let amplitudeDef = NodeParameterDef(
33+
identifier: "amplitude",
34+
name: "Amplitude.",
35+
address: akGetParameterAddress("PhaseLockedVocoderParameterAmplitude"),
36+
defaultValue: 1,
37+
range: 0 ... 1,
38+
unit: .generic)
39+
40+
/// Amplitude.
41+
@Parameter(amplitudeDef) public var amplitude: AUValue
42+
43+
/// Specification for pitch ratio
44+
public static let pitchRatioDef = NodeParameterDef(
45+
identifier: "pitchRatio",
46+
name: "Pitch ratio. A value of. 1 normal, 2 is double speed, 0.5 is halfspeed, etc.",
47+
address: akGetParameterAddress("PhaseLockedVocoderParameterPitchRatio"),
48+
defaultValue: 1,
49+
range: 0 ... 1_000,
50+
unit: .hertz)
51+
52+
/// Pitch ratio. A value of. 1 normal, 2 is double speed, 0.5 is halfspeed, etc.
53+
@Parameter(pitchRatioDef) public var pitchRatio: AUValue
54+
55+
// MARK: - Initialization
56+
57+
/// Initialize this vocoder node
58+
///
59+
/// - Parameters:
60+
/// - file: AVAudioFile to load into memory
61+
/// - position: Position in time. When non-changing it will do a spectral freeze of a the current point in time.
62+
/// - amplitude: Amplitude.
63+
/// - pitchRatio: Pitch ratio. A value of. 1 normal, 2 is double speed, 0.5 is halfspeed, etc.
64+
///
65+
public init(
66+
file: AVAudioFile,
67+
position: AUValue = positionDef.defaultValue,
68+
amplitude: AUValue = amplitudeDef.defaultValue,
69+
pitchRatio: AUValue = pitchRatioDef.defaultValue
70+
) {
71+
setupParameters()
72+
73+
loadFile(file)
74+
75+
self.position = position
76+
self.amplitude = amplitude
77+
self.pitchRatio = pitchRatio
78+
}
79+
80+
internal func loadFile(_ avAudioFile: AVAudioFile) {
81+
Exit: do {
82+
var err: OSStatus = noErr
83+
var theFileLengthInFrames: Int64 = 0
84+
var theFileFormat = AudioStreamBasicDescription()
85+
var thePropertySize: UInt32 = UInt32(MemoryLayout.stride(ofValue: theFileFormat))
86+
var extRef: ExtAudioFileRef?
87+
var theData: UnsafeMutablePointer<CChar>?
88+
var theOutputFormat = AudioStreamBasicDescription()
89+
90+
err = ExtAudioFileOpenURL(avAudioFile.url as CFURL, &extRef)
91+
if err != 0 { Log("ExtAudioFileOpenURL FAILED, Error = \(err)"); break Exit }
92+
// Get the audio data format
93+
guard let externalAudioFileRef = extRef else {
94+
break Exit
95+
}
96+
err = ExtAudioFileGetProperty(externalAudioFileRef,
97+
kExtAudioFileProperty_FileDataFormat,
98+
&thePropertySize,
99+
&theFileFormat)
100+
if err != 0 {
101+
Log("ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = \(err)")
102+
break Exit
103+
}
104+
if theFileFormat.mChannelsPerFrame > 2 {
105+
Log("Unsupported Format, channel count is greater than stereo")
106+
break Exit
107+
}
108+
109+
theOutputFormat.mSampleRate = Settings.sampleRate
110+
theOutputFormat.mFormatID = kAudioFormatLinearPCM
111+
theOutputFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat
112+
theOutputFormat.mBitsPerChannel = UInt32(MemoryLayout<Float>.stride) * 8
113+
theOutputFormat.mChannelsPerFrame = 1 // Mono
114+
theOutputFormat.mBytesPerFrame = theOutputFormat.mChannelsPerFrame * UInt32(MemoryLayout<Float>.stride)
115+
theOutputFormat.mFramesPerPacket = 1
116+
theOutputFormat.mBytesPerPacket = theOutputFormat.mFramesPerPacket * theOutputFormat.mBytesPerFrame
117+
118+
// Set the desired client (output) data format
119+
err = ExtAudioFileSetProperty(externalAudioFileRef,
120+
kExtAudioFileProperty_ClientDataFormat,
121+
UInt32(MemoryLayout.stride(ofValue: theOutputFormat)),
122+
&theOutputFormat)
123+
if err != 0 {
124+
Log("ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = \(err)")
125+
break Exit
126+
}
127+
128+
// Get the total frame count
129+
thePropertySize = UInt32(MemoryLayout.stride(ofValue: theFileLengthInFrames))
130+
err = ExtAudioFileGetProperty(externalAudioFileRef,
131+
kExtAudioFileProperty_FileLengthFrames,
132+
&thePropertySize,
133+
&theFileLengthInFrames)
134+
if err != 0 {
135+
Log("ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = \(err)")
136+
break Exit
137+
}
138+
139+
// Read all the data into memory
140+
let dataSize = UInt32(theFileLengthInFrames) * theOutputFormat.mBytesPerFrame
141+
theData = UnsafeMutablePointer.allocate(capacity: Int(dataSize))
142+
if theData != nil {
143+
var bufferList: AudioBufferList = AudioBufferList()
144+
bufferList.mNumberBuffers = 1
145+
bufferList.mBuffers.mDataByteSize = dataSize
146+
bufferList.mBuffers.mNumberChannels = theOutputFormat.mChannelsPerFrame
147+
bufferList.mBuffers.mData = UnsafeMutableRawPointer(theData)
148+
149+
// Read the data into an AudioBufferList
150+
var ioNumberFrames: UInt32 = UInt32(theFileLengthInFrames)
151+
err = ExtAudioFileRead(externalAudioFileRef, &ioNumberFrames, &bufferList)
152+
if err == noErr {
153+
// success
154+
let data = UnsafeMutablePointer<Float>(
155+
bufferList.mBuffers.mData?.assumingMemoryBound(to: Float.self)
156+
)
157+
au.setWavetable(data: data, size: Int(ioNumberFrames))
158+
} else {
159+
// failure
160+
theData?.deallocate()
161+
theData = nil // make sure to return NULL
162+
Log("Error = \(err)"); break Exit
163+
}
164+
}
165+
}
166+
}
167+
168+
}

0 commit comments

Comments
 (0)