DSWaveformImage

repository·main·Indexed 23 days ago

https://github.com/dmrschmidt/dswaveformimage

A native audio waveform rendering library for Apple platforms (iOS, iPadOS, macOS, visionOS, and Mac Catalyst). It provides high-level SwiftUI and UIKit views, a raw drawing API for generating images via WaveformImageDrawer, and an analyzer for raw audio samples. Features include linear and circular renderers, spectral tinting, amplitude scaling, and support for real-time live audio waveform rendering.

Tokens
3K
Snippets
12
Records
17
Agent score
29%

What's inside DSWaveformImage

  1. Migrate to DSWaveformImage v15.0.0 (Upcoming)

    main

    When upgrading to version 15.0.0, be aware of the following breaking changes and new features:

    • Waveform.Style.spectralTint(low:high:): A new style case has been added. If you use exhaustive switch statements over Waveform.Style, you must add this case or use @unknown default.
    • Position.middle rendering: Waveforms centered with .middle now render smaller at verticalScalingFactor=1. They are constrained to fill exactly half the available canvas height in each direction. To achieve the previous visual size, increase the verticalScalingFactor.
    • Stereo Damping: Damping is now applied to each channel independently. Previously, damping was applied to the concatenated array, which caused issues at the transition between Left and Right channels.
    • Waveform.AmplitudeScaling: A new enum has been introduced. It defaults to .absolute to preserve prior behavior. You can configure this using the amplitudeScaling: parameter in Waveform.Configuration.init or with(...).
    • WaveformAnalyzer.analyze(...): This method now returns both amplitudes and per-slot spectral centroids in a single pass.
    • LinearWaveformRenderer: Now conforms to the SpectralAwareWaveformRenderer protocol.
  2. Install DSWaveformImage via SPM

    main

    Add the package via Swift Package Manager using the following URL. It supports versions up to the next major version from 14.0.0.

    https://github.com/dmrschmidt/DSWaveformImage

    After adding the package, import the modules based on your needs:

    • import DSWaveformImage: Core functionality (drawer, analyzer, renderers, types).
    • import DSWaveformImageViews: UI components (UIKit and SwiftUI views).
    import DSWaveformImage       // core: drawer, analyzer, renderers, types
    import DSWaveformImageViews  // UIKit + SwiftUI views (optional)
  3. Migrate to DSWaveformImage v13.0.0

    main

    Key changes in version 13.0.0:

    • Renamed Property: dampening has been renamed to damping throughout the library (specifically in Waveform.Configuration).
    • New Styles: .outlined and .gradientOutlined were added to Waveform.Style.
    • Positioning: Waveform.Position was removed. Positioning responsibility has been moved to the parent view.
  4. Migrate to DSWaveformImage v11.0.0

    main

    Key changes in version 11.0.0:

    • Module Split: The library is split into DSWaveformImage and DSWaveformImageViews. If you use the native SwiftUI/UIKit views, you must add import DSWaveformImageViews to your file.
    • SwiftUI Bindings: SwiftUI views have moved from using Binding to using plain values.
  5. Migrate to DSWaveformImage v12.0.0

    main

    Key changes in version 12.0.0:

    • Renderer Abstraction: The rendering pipeline is now decoupled from analysis. You can implement custom renderers by conforming to the WaveformRenderer protocol.
    • New Renderer: CircularWaveformRenderer was introduced.
    • Configuration: position was removed from Waveform.Configuration.
  6. Quick start with SwiftUI, UIKit, or Raw API

    main

    Depending on your integration layer, use the following patterns to render waveforms:

    SwiftUI Use the WaveformView component.

    UIKit Use the WaveformImageView component.

    Raw API Use WaveformImageDrawer to generate a UIImage or NSImage directly.

    // SwiftUI
    WaveformView(audioURL: url)
    
    // UIKit
    let view = WaveformImageView(frame: .init(x: 0, y: 0, width: 500, height: 300))
    view.waveformAudioURL = url
    
    // Raw UIImage / NSImage
    let image = try await WaveformImageDrawer().waveformImage(
        fromAudioAt: url,
        with: .init(size: size, style: .filled(.black))
    )
  7. Migrate to DSWaveformImage v14.0.0

    main

    Key changes in version 14.0.0:

    • Deployment Targets: Minimum requirements are now iOS 15.0 and macOS 12.0.
    • Error Handling: WaveformAnalyzer and WaveformImageDrawer now return a Result<[Float] | DSImage, Error> type when using completion handlers.
    • WaveformAnalyzer API: The analyzer is now stateless. Instead of passing the URL to the constructor, use the samples(fromAudioAt:count:qos:) method.
    • WaveformView: A new constructor is available that exposes the underlying WaveformShape.
  8. Render live audio waveforms

    main

    For real-time rendering of a [Float] sample stream, use the live view components. These should be paired with a source like AVAudioRecorder that provides per-frame amplitudes.

    SwiftUI Use WaveformLiveCanvas(samples:shouldDrawSilencePadding:).

    UIKit Use WaveformLiveView and call .add(sample:) as new amplitudes arrive.

    // SwiftUI
    WaveformLiveCanvas(samples: recorder.samples, shouldDrawSilencePadding: true)
    
    // UIKit
    let view = WaveformLiveView()
    recorder.updateMeters()
    let amplitude = 1 - pow(10, recorder.averagePower(forChannel: 0) / 20)
    view.add(sample: amplitude)
  9. Capture iOS simulator screenshots for documentation

    main

    To capture and crop screenshots from the iOS simulator for use in documentation, follow these steps using xcrun and ImageMagick:

    1. Launch the example app with a specific tab (e.g., tab 2 or 3): xcrun simctl launch <udid> de.dmrschmidt.DSWaveformImageExample-iOS -tab 2
    2. Take a raw screenshot: xcrun simctl io <udid> screenshot raw.png
    3. Crop the image using magick: magick raw.png -crop 1206x2343+0+177 +repage live-recording.png
    xcrun simctl launch <udid> de.dmrschmidt.DSWaveformImageExample-iOS -tab 2
    xcrun simctl io <udid> screenshot raw.png
    magick raw.png -crop 1206x2343+0+177 +repage live-recording.png
  10. Apply Spectral Tint to waveforms

    main

    .spectralTint(low:high:) colors each amplitude column based on its spectral centroid. Bass-heavy columns use the low color, while treble-heavy columns use the high color, with smooth interpolation between them.

    Note: This requires a renderer that conforms to SpectralAwareWaveformRenderer. LinearWaveformRenderer conforms by default. If a renderer does not support spectral data, it will fall back to filling with the low color.

    WaveformView(audioURL: url, configuration: .init(
        style: .spectralTint(low: .systemBlue, high: .systemRed)
    ))
  11. Apply Damping to waveforms

    main

    Waveform.Damping fades the envelope toward zero at one or both ends. This is useful for live capture to avoid hard cuts at the leading or trailing edges.

    Use Damping(percentage:sides:) where percentage is the fade amount and sides can be .both, .up, or .down. You can also provide a custom easing: closure to shape the falloff.

    .init(style: .filled(.indigo), damping: .init(percentage: 0.18, sides: .both))