Skip to content

Commit

Permalink
Updated app
Browse files Browse the repository at this point in the history
  • Loading branch information
PABannier committed May 8, 2024
1 parent 0911670 commit 3301e5d
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
E091A4832BEB788F004CCD19 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E091A4822BEB788F004CCD19 /* Preview Assets.xcassets */; };
E091A48B2BEB7930004CCD19 /* LibBark.swift in Sources */ = {isa = PBXBuildFile; fileRef = E091A4892BEB7930004CCD19 /* LibBark.swift */; };
E091A4902BEB83D4004CCD19 /* bark in Frameworks */ = {isa = PBXBuildFile; productRef = E091A48F2BEB83D4004CCD19 /* bark */; };
E091A4922BEBA586004CCD19 /* BarkState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E091A4912BEBA586004CCD19 /* BarkState.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -24,6 +25,7 @@
E091A4822BEB788F004CCD19 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
E091A4892BEB7930004CCD19 /* LibBark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibBark.swift; sourceTree = "<group>"; };
E091A48D2BEB7A9F004CCD19 /* bark.cpp */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = bark.cpp; path = ../../..; sourceTree = "<group>"; };
E091A4912BEBA586004CCD19 /* BarkState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkState.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -64,6 +66,7 @@
E091A47E2BEB788F004CCD19 /* Assets.xcassets */,
E091A4802BEB788F004CCD19 /* BarkCppDemo.entitlements */,
E091A4812BEB788F004CCD19 /* Preview Content */,
E091A4912BEBA586004CCD19 /* BarkState.swift */,
);
path = BarkCppDemo;
sourceTree = "<group>";
Expand Down Expand Up @@ -163,6 +166,7 @@
E091A47D2BEB788D004CCD19 /* ContentView.swift in Sources */,
E091A47B2BEB788D004CCD19 /* BarkCppDemoApp.swift in Sources */,
E091A48B2BEB7930004CCD19 /* LibBark.swift in Sources */,
E091A4922BEBA586004CCD19 /* BarkState.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Binary file not shown.
114 changes: 114 additions & 0 deletions examples/swiftui/BarkCppDemo/BarkCppDemo/BarkState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//
// BarkState.swift
// BarkCppDemo
//
// Created by Pierre-Antoine BANNIER on 08/05/2024.
//

import Foundation
import AVFoundation

let kSampleRate: Double = 44100;
let kNumChannels: UInt32 = 1;


@MainActor
class BarkState: NSObject, ObservableObject {
@Published var isModelLoaded = false
@Published var messageLog = ""
@Published var canGenerate = false
@Published var isGenerating = false
@Published var isPlaying = false

private var barkContext: BarkContext?
private var audioPlayer: AVAudioPlayer?

private var modelUrl: URL? {
Bundle.main.url(forResource: "ggml-weight", withExtension: "bin", subdirectory: "models")
}

private var generatedAudioUrl: URL? {
Bundle.main.url(forResource: "output", withExtension: "wav", subdirectory: "generated")
}

private enum LoadError: Error {
case couldNotLocateModel
}

override init() {
super.init()
do {
try loadModel()
canGenerate = true
} catch {
print(error.localizedDescription)
messageLog += "\(error.localizedDescription)"
}
}

private func loadModel() throws {
messageLog += "Loading model...\n"
if let modelUrl {
barkContext = try BarkContext.createContext(path: modelUrl.path(), seed: 0)
messageLog += "Loaded model \(modelUrl.lastPathComponent)"
} else {
messageLog += "Could not locate model\n"
}
}

func generateAudioFromText(prompt: String) async {
if (!canGenerate) {
return
}
guard let barkContext else {
return
}

do {
canGenerate = false
messageLog += "Generating audio...\n"
let audioArray = try await barkContext.generateAudio(text: prompt)
messageLog += "Audio generated!\n"
loadAudioInPlayer(samples: audioArray)
} catch {
print(error.localizedDescription)
messageLog += "\(error.localizedDescription)"
}

canGenerate = true
}

private func loadAudioInPlayer(samples: [Float]) {
let audioFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: kSampleRate, channels: kNumChannels, interleaved: false)!
var pcmBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: AVAudioFrameCount(samples.count))!
pcmBuffer.frameLength = pcmBuffer.frameCapacity

let channelMemory = pcmBuffer.floatChannelData!
for channel in 0..<Int(kNumChannels) {
for i in 0..<samples.count {
channelMemory[channel][i] = samples[i]
}
}

// Create the audio player
do {
let audioFile = try AVAudioFile(forWriting: FileManager.default.temporaryDirectory.appendingPathComponent("temp.wav"), settings: audioFormat.settings)
try audioFile.write(from: pcmBuffer)

// Rewind and prepare to play
audioPlayer = try AVAudioPlayer(contentsOf: audioFile.url, fileTypeHint: AVFileType.wav.rawValue)
audioPlayer?.prepareToPlay()
} catch {
print("Failed to create audio player: \(error.localizedDescription)")
messageLog += "\(error.localizedDescription)"
}
}

func startPlayback() {
audioPlayer?.play()
}

func stopPlayback() {
audioPlayer?.pause()
}
}
45 changes: 39 additions & 6 deletions examples/swiftui/BarkCppDemo/BarkCppDemo/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,47 @@
import SwiftUI

struct ContentView: View {
@StateObject var barkState = BarkState()
@State private var textInput: String = ""

var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
NavigationStack {
VStack {
TextField("Enter your text here", text: $textInput)
.padding()
.textFieldStyle(RoundedBorderTextFieldStyle())
.multilineTextAlignment(.leading)
.frame(maxWidth: .infinity)

HStack {
Button("Generate Audio", action: {
Task {
await barkState.generateAudioFromText(prompt: textInput)
}
})
.buttonStyle(.bordered)
.disabled(!barkState.canGenerate || barkState.isGenerating)

Button(barkState.isPlaying ? "Pause" : "Play", action: {
if barkState.isPlaying {
barkState.stopPlayback()
} else {
barkState.startPlayback()
}
barkState.isPlaying.toggle()
})
.buttonStyle(.bordered)
.disabled(!barkState.canGenerate)
}

ScrollView {
Text(verbatim: barkState.messageLog)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.navigationTitle("Bark SwiftUI Demo")
.padding()
}
.padding()
}
}

Expand Down

0 comments on commit 3301e5d

Please sign in to comment.