AudioKit, AKPlayer: How to play from Samples, not time

Viewed 625

I am currently using FDWaveFormView to great success to display waveforms representing audio I record from AKMicrophone or AKAudioFile.

I am successfully able to highlight specific regions in the waveform and FDwaveForm gives back a range of the samples from the audiofile.

My problem now is I cannot find an appropriate method in AKPlayer that would let me play from a start sample to an end sample.

I noticed that AKSamplePlayer is now deprecated, but it did have a method:play(from: Sample, to: Sample)

My guess is that I would be able to do some math to translate Sample position to time (as a Double as prescribed in AKPlayer), however I have not found the appropriate math or functions to do this, any hints?

To be very explicit in what I am trying to do, please refer to the image below:

How to get AKPlayer to play from start and end samples

note for any AudioKit core members who may see this question, I know there are a variety of AudioKitUI components that may of made this easier, however only FDWaveFormView has given me the functionality I need for this particular app, i'm happy to discuss further offline, thanks again so much.

EDIT

I've come up with some code that I believe has solved it:

let startingSampleIndex = self.waveformPlot.highlightedSamples!.min()
let endingSampleIndex = self.waveformPlot.highlightedSamples!.max()
let millisecondsPerSample : Double = 1000 / 44100

let startingDuration : Double = (startingSampleIndex! * millisecondsPerSample) / 1000
let endingDuration : Double = (endingSampleIndex! * millisecondsPerSample) / 1000

print("StartSample:\(startingSampleIndex!) | EndSample:\(endingSampleIndex!) | milliPerSample:\(millisecondsPerSample) | StartDuration:\(startingDuration) | EndDuration:\(endingDuration)")
player.play(from: startingDuration, to: endingDuration)

The main equation being numberOfSamples * millisecondsPerSample = timeInMilliseconds by dividing by 1000 I can normalize everything to seconds which is what AKPlayer wants. If anyone sees something problematic here I'd love the advice but I think this has done it! Sorry I am still new to DSP and so thankful for AudioKit being an incredible Shepard into this world!

2 Answers

To convert from frames to seconds you should divide by the sample rate of the audio file, not a hardcoded 44100 value:

    guard let frameRange = self.waveformPlot.highlightedSamples else { return }
    let startTime = frameRange.min() / audioFile.fileFormat.sampleRate
    let endTime = frameRange.max() / audioFile.fileFormat.sampleRate
    player.play(from: startTime, to: endTime)

I found the solution, essentially RTFM on DSP 101 and samples :

let startingSampleIndex = self.waveformPlot.highlightedSamples!.min()
let endingSampleIndex = self.waveformPlot.highlightedSamples!.max()
let millisecondsPerSample : Double = 1000 / 44100

let startingDuration : Double = (startingSampleIndex! * millisecondsPerSample) / 1000
let endingDuration : Double = (endingSampleIndex! * millisecondsPerSample) / 1000

print("StartSample:\(startingSampleIndex!) | EndSample:\(endingSampleIndex!) | milliPerSample:\(millisecondsPerSample) | StartDuration:\(startingDuration) | EndDuration:\(endingDuration)")
player.play(from: startingDuration, to: endingDuration)

This is working excellently, thanks again to both FDWaveFormView and AudioKit!

Related