Full example of generation and saving:
import AVFoundation
import Foundation
struct FMSynth {
static let sampleRate = 44100.0
static let carrierFrequency: Float32 = 440.0
static let unitVelocity = Float32(2.0 * .pi / sampleRate)
static let modulatorFrequency: Float32 = 679.0
static let channels: UInt32 = 1
let modulatorAmplitude: Float32 = 0.8
let carrierVelocity = carrierFrequency * unitVelocity
let modulatorVelocity = modulatorFrequency * unitVelocity
let samplesPerBuffer: AVAudioFrameCount = 1024 * 16
let engine = AVAudioEngine()
let player = AVAudioPlayerNode()
let format = AVAudioFormat(
standardFormatWithSampleRate: sampleRate,
channels: channels
)
func generateAndPlay() {
do {
if let buffer = AVAudioPCMBuffer(pcmFormat: format!, frameCapacity: samplesPerBuffer) {
// generate
let channelL = buffer.floatChannelData?[0]
let channelR = buffer.floatChannelData?[1]
var sampleTime: Float32 = 0
for sampleIndex in 0..<Int(samplesPerBuffer) {
let sample = sin(carrierVelocity * sampleTime + modulatorAmplitude * sin(modulatorVelocity * sampleTime))
channelL?[sampleIndex] = sample
channelR?[sampleIndex] = sample
sampleTime += 1.0
}
buffer.frameLength = samplesPerBuffer
// save to file
let settings: [String: Any] = [
AVFormatIDKey : buffer.format.settings[AVFormatIDKey] ?? kAudioFormatLinearPCM,
AVNumberOfChannelsKey : buffer.format.settings[AVNumberOfChannelsKey] ?? 1,
AVSampleRateKey : buffer.format.settings[AVSampleRateKey] ?? 44100,
AVLinearPCMBitDepthKey: buffer.format.settings[AVLinearPCMBitDepthKey] ?? 16
]
let fileURL = URL(filePath: "/tmp/out.wav")
let file = try AVAudioFile(forWriting: fileURL, settings: settings, commonFormat: .pcmFormatFloat32, interleaved: true)
try file.write(from: buffer)
file.close()
// play
engine.attach(player)
engine.connect(player, to: engine.mainMixerNode, format: format)
try engine.start()
player.scheduleBuffer(buffer)
player.play()
}
} catch {
print("Error: \(error).")
}
}
}
let fmSynth = FMSynth()
fmSynth.generateAndPlay()
Post
Replies
Boosts
Views
Activity
Try using this variant:
Circle()
.fill(Color.red)
.frame(width: 100, height: 100, alignment: .center)
.onLongPressGesture(minimumDuration: 2) {
print("Long pressed!")
} onPressingChanged: { inProgress in
print("In progress: \(inProgress)!")
}
macOS Sequoia has started to fully control security.
The issue is with App Groups in xCode.
The app developer in xCode should go to the section (repeat for each target):
Signing & Capabilities → Targets → TARGET_NAME → App Groups → App Group
in which he should specify the following:
$(TeamIdentifierPrefix)myFirm.myName
A fictitious ID like this does not work:
myGroupID.myFirm.myName
And in the program code he should specify the real group ID (in numbers)
let storeDirectory = FileManager.default.containerURL(
forSecurityApplicationGroupIdentifier: “0123456789.myFirm.myName”
)
After recompiling the app, the problem disappears.
I had the same problem after updating to Sequoia - every time I launch the application, a window started appearing asking me to approve the action "Application wants to access the data of another application".
I changed the values to these in my application and everything worked:
File "*.entitlements":
<key>com.apple.security.application-groups</key>
<array>
- <string>maxrys.js-blocker.group</string>
+ <string>$(TeamIdentifierPrefix)maxrys.js-blocker</string>
</array>
File "modelDomains.swift":
public class Domains: NSManagedObject {
@NSManaged var name: String
static let context: NSManagedObjectContext = {
- let appGrpName = "maxrys.js-blocker.group"
+ let appGrpName = "97CZR6J379.maxrys.js-blocker"
let storeDirectory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGrpName)!
let storeURL = storeDirectory.appendingPathComponent("Database.sqlite")
let storeDescription = NSPersistentStoreDescription(url: storeURL)
let container = NSPersistentContainer(name: "Model")
container.persistentStoreDescriptions = [storeDescription]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container.viewContext
}()
convenience init() {
self.init(context: Domains.context)
}
static func selectAll(orderBy: String = #keyPath(Domains.name), ascending: Bool = true) -> [Domains] {
let fetchRequest = NSFetchRequest<Domains>(entityName: "Domains")
let sortDescriptorKey = NSSortDescriptor(key: orderBy, ascending: ascending)
fetchRequest.sortDescriptors = [sortDescriptorKey]
return try! self.context.fetch(
fetchRequest
)
}
}
You can get your Team ID here: https://developer.apple.com/account → Membership details → Team ID
This only works for the selected domain and only on the https protocol.
Info.plist
<key>SFSafariWebsiteAccess</key>
<dict>
<key>Level</key>
<string>All</string>
<key>Allowed Domains for Header Injection</key>
<array>
<string>js-blocker.com</string>
</array>
</dict>
SafariExtensionHandler.swift
class SafariExtensionHandler: SFSafariExtensionHandler {
override func additionalRequestHeaders(for url: URL, completionHandler: @escaping ([String : String]?) -> Void) {
print("FIRE: additionalRequestHeaders")
}
}
Here is a code example that will explain everything:
class SafariExtensionHandler: SFSafariExtensionHandler {
override func toolbarItemClicked(in window: SFSafariWindow) {
// when: info.plist → SFSafariToolbarItem → Action = Command
}
override func popoverWillShow(in window: SFSafariWindow) {
// when: info.plist → SFSafariToolbarItem → Action = Popover
}
override func popoverViewController() -> SFSafariExtensionViewController {
// when: info.plist → SFSafariToolbarItem → Action = Popover
return SafariExtensionViewController.shared
}
}