Skip to content

Audio Visualizer #22

Open
Open

Description

@AppDevGuy

Add the ability to visualise the recorded audio and a basic view.

Activity

  1. added this to the Version 0.4 milestone on Aug 24, 2020
  2. self-assigned this
    on Aug 24, 2020
  3. crazypoo commented on Mar 21, 2023

    @crazypoo

    Hello,friend,I finish this topic

  4. huangboju commented on Jul 19, 2025

    @huangboju

    This is my solution

    input.installTap(onBus: bus, bufferSize: 8192, format: recordingFormat) { [weak self] (buffer, _) -> Void in
                var newBufferAvailable = true
                let inputCallback: AVAudioConverterInputBlock = { _, outStatus in
                    if newBufferAvailable {
                        outStatus.pointee = .haveData
                        newBufferAvailable = false
                        return buffer
                    } else {
                        outStatus.pointee = .noDataNow
                        return nil
                    }
                }
                let convertedBuffer = AVAudioPCMBuffer(pcmFormat: outputFormat, frameCapacity: AVAudioFrameCount(outputFormat.sampleRate) * buffer.frameLength / AVAudioFrameCount(buffer.format.sampleRate))!
                var error: NSError?
                let status = converter.convert(to: convertedBuffer, error: &error, withInputFrom: inputCallback)
                if status == .error {
                    self?.delegate?.didFailToCommenceSpeechRecording()
                    self?.delegate?.didFailToProcessRequest(withError: OSSSpeechKitErrorType.invalidAudioEngine.error)
                    if let err = error {
                        self?.debugLog(object: self as Any, message: "Audio Engine conversion error: \(err)")
                    }
                    return
                }
                self?.request?.append(convertedBuffer)
                self?.processAudioBuffer(convertedBuffer)
            }
    
    private func processAudioBuffer(_ buffer: AVAudioPCMBuffer) {
            guard let channelData = buffer.floatChannelData?[0] else { return }
    
            let channelDataValue = channelData
            let channelDataValueArray = stride(from: 0, to: Int(buffer.frameLength), by: buffer.stride).map { channelDataValue[$0] }
    
            // 计算RMS (Root Mean Square) 音量
            let rms = sqrt(channelDataValueArray.map { $0 * $0 }.reduce(0, +) / Float(channelDataValueArray.count))
    
            // 转换为分贝并标准化
            let decibels = min(max(20 * log10(rms), -60), 0)
    
            let normalizedVolume = (decibels + 60) / 60.0 // 标准化到 0-1 范围
    
            DispatchQueue.main.async {
                self.delegate?.didProcessAudioBuffer(normalizedVolume)
            }
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

In ProgressTasks that are in progressenhancementNew feature or requestv0.4Version 0.4

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions