Skip to content

Commit

Permalink
Add basic doc comments (#2)
Browse files Browse the repository at this point in the history
Adds doc comments on some of the core types.
  • Loading branch information
MaxDesiatov committed Mar 13, 2024
1 parent a892192 commit 1745f5e
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 6 deletions.
7 changes: 4 additions & 3 deletions Sources/swift-audio/AudioBuffer.swift
Expand Up @@ -10,14 +10,15 @@
//
//===----------------------------------------------------------------------===//

/// A non-copyable buffer of audio samples.
struct AudioBuffer: ~Copyable {
let storage: UnsafeMutableBufferPointer<Float>

init(capacity: Int) {
/// Allocates an audio buffer and fills it with samples from a given signal.
/// - Parameter capacity: the number of samples
init(capacity: Int, source: inout some Signal) {
self.storage = .allocate(capacity: capacity)
}

func fill(source: inout some Signal) {
for i in self.storage.indices {
let sample = source.next()
self.storage[i] = sample
Expand Down
14 changes: 14 additions & 0 deletions Sources/swift-audio/Waveforms/Saw.swift
Expand Up @@ -10,17 +10,31 @@
//
//===----------------------------------------------------------------------===//

/// Number of samples generated per second.
let sampleRate = 44_100

/// Stateless sawtooth-shaped waveform function.
/// - Parameters:
/// - time: Number of seconds passed since the current oscillation started.
/// - frequency: Frequency of oscillation, in hertz.
/// - Returns: An audio sample in the normalized range of -1.0...1.0
func saw(time: Float, frequency: Float) -> Float {
let phase = time * frequency

return 2 * (phase - (0.5 + phase).rounded(.down))
}

/// Stateful sawtooth-shaped signal.
struct Saw: Signal {
/// Frequency of oscillation, in hertz.
var frequency: Float = 440.0

/// The "volume" of the signal, i.e. the absolute boundary of the range in which this signal oscillates. Default
/// amplitude of 1.0 means that samples returned from ``Saw/next()`` will always stay in `-1.0...1.0` range.
var amplitude: Float = 1.0

/// Number of seconds passed since the current oscillation started. To avoid overflowing, this value is reset t
/// 0.0 after every oscillation.
var currentTime: Float = 0.0

mutating func next() -> Float {
Expand Down
3 changes: 3 additions & 0 deletions Sources/swift-audio/Waveforms/Signal.swift
Expand Up @@ -10,6 +10,9 @@
//
//===----------------------------------------------------------------------===//

/// An abstract digital signal that produces an infinite amount of samples.
protocol Signal {
/// Updates current state of the signal and produces the next sample.
/// - Returns: The latest sample in this signal.
mutating func next() -> Float
}
13 changes: 12 additions & 1 deletion Sources/swift-audio/Waveforms/Square.swift
Expand Up @@ -10,15 +10,26 @@
//
//===----------------------------------------------------------------------===//

/// Stateful square-shaped waveform. For values of ``Square/pulseWidth`` other than the default 0.5, strictly speaking
/// it produces a rectangular-shaped waveform.
struct Square: Signal {
/// Frequency of oscillations in hertz.
var frequency: Float {
didSet {
self.saw.frequency = self.frequency
}
}

/// The "volume" of the signal, i.e. the absolute boundary of the range in which this signal oscillates. Default
/// amplitude of 1.0 means that samples returned from ``Square/next()`` will always stay in `-1.0...1.0` range.
var amplitude: Float

/// The ratio of a width of a pulse in this waveform in the range of `0.0..<1.0`. The default value of 0.5 makes
/// the pulse look like a square. Values smaller than 0.5 will make it more narrow, values larger than 0.5 make it
/// wider.
var pulseWidth: Float

/// The underlying saw-shaped waveform used as a helper to compute samples.
private var saw: Saw

init(
Expand All @@ -39,4 +50,4 @@ struct Square: Signal {
-amplitude
}
}
}
}
6 changes: 6 additions & 0 deletions Sources/swift-audio/Waveforms/Triangle.swift
Expand Up @@ -12,10 +12,16 @@

import VultDSP

/// Stateful triangle-shaped waveform.
struct Triangle: Signal {
/// The pitch parameter of the waveform that sets its tone.
var pitch: Pitch

/// The "volume" of the signal, i.e. the absolute boundary of the range in which this signal oscillates. Default
/// amplitude of 1.0 means that samples returned from ``Triangle/next()`` will always stay in `-1.0...1.0` range.
var amplitude: Float = 1.0

/// The state managed by the underlying VultDSP implementation of the signal.
var state = Triangle__ctx_type_0()

mutating func next() -> Float {
Expand Down
6 changes: 4 additions & 2 deletions Sources/swift-audio/main.swift
Expand Up @@ -48,8 +48,10 @@ func main() {
)

let totalLengthInSeconds = 6
let buffer = AudioBuffer(capacity: sampleRate * totalLengthInSeconds)
buffer.fill(source: &mixer)
let buffer = AudioBuffer(
capacity: sampleRate * totalLengthInSeconds,
source: &mixer
)
Audio.encode(buffer)

Plotter<HTMLCanvas>(
Expand Down

0 comments on commit 1745f5e

Please sign in to comment.