Am using the demo code below to flesh out an audio recording app in Swift 5.x
I would like to monitor certain aspects of the AVAudioRecorder as it is recording. Such as: frequency, power, volume, etc. but in live time.
I found an example in Swift 3 where the user sets up a callback timer for 0.5 sec. I was wondering if this was still the case, or that in the latest version of Swift, there might be a callback function in the AVAudioEngine that gets called at a regular frequency?
do {
audioRecorder = try AVAudioRecorder(url: audioFilename!, settings: settings)
audioRecorder.delegate = self
audioRecorder.record()
recordButton.setTitle("Tap to Stop", for: .normal)
} catch {
finishRecording(success: false)
}
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I was under the impression, with offline speech to text, that there was no limit. Since the app wouldn't be using Apple's servers in real time.
Yet when I process: speechRecognizer.recognitionTask it quits after one minute.
Did I misread something ?
it's a great tool from Apple, but I want to delve more into its engine as I need to. The documentation doesn't seem to go there. For instance, I can't figure out how to clear the bestTranscritption object in speechRecognizer, as it always contains the entire transcription. There are other things I would like to work with as well.
Has anyone worked with this heavily enough to recommend proper books are paid for tutorials?
Many thanks
Building a very simple voice-to-text app, which I got from an online demo.
What I can't seem to find is how to reset the response back to nil. This demo just keeps transcribing from the very beginning till it finally stalls.
While I don't know how if the stall is related to my question, I still need to find out how to code "Ok, got the first 100 words. Reset response text to nil. Continue."
func startSpeechRecognition(){
let node = audioEngine.inputNode
let recordingFormat = node.outputFormat(forBus: 0)
node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat, block: { (buffer, _) in self.request.append(buffer)})
audioEngine.prepare()
do {
try audioEngine.start()
} catch let error {
alertView(message: "audioEngine start error")
}
guard let myRecognition = SFSpeechRecognizer() else {
self.alertView(message: "Recognition is not on your phone")
return
}
if !myRecognition.isAvailable {
self.alertView(message: "recognition is not available right now")
}
task = speechRecognizer?.recognitionTask(with: request, resultHandler: { (response, error) in
guard let response = response else {
if error != nil {
self.alertView(message: error!.localizedDescription.debugDescription)
} else {
self.alertView(message: "Unknow error in creating task")
}
return
}
let message = response.bestTranscription.formattedString
self.label.text = message
})
}
Copied the code below from a tutorial, and I mostly understand what is going on. But I'd like to be able to fully read it.
What I do get is that:
handler can be nil, but here it's the code to run upon the completion of UIAlertAction.
But am unsure what (_) in is. I have also sometimes seen it as [self] in
Thank you
controller.addAction(UIAlertAction(title: "OK", style: .default, handler: { (_) in controller.dismiss(animated: true, completion: nil)}))
I've learned the hard way that specific commands to add a child UIView must be in a certain order, especially if I am bringing in the child UIView using animation.
So I'd like to be clear that what the order I use to delete a child UIView is correct. Yes, what I have below works. But that doesn't mean it's correct.
Thank you
UIView.transition(with: parent, duration: 0.5, options: .transitionCurlUp, animations: { [self] in
self.willMove(toParent: nil);
self.removeFromParent();
self.view.removeFromSuperview();
self.dismiss(animated: false, completion: nil);
}, completion:nil)
Thanks to people on this board I am able to successfully calla up a child UIViewConroller via animation with:
This is the buttonAction from the Main UIViewController, which calls up setController
@objc func buttonAction(sender: UIButton!) {
guard let theButton = sender as? MyButton else { return}
UIView.transition(with: self.view, duration: 0.5, options: .transitionCurlDown, animations: { [self] in
self.addChild(setController);
self.view.addSubview(setController.view);
}, completion: { [self]_ in setController.didMove(toParent: self);
setController.doLayout();})
}
the doLayout method lies within the child:
func doLayout (){
guard let parent = cView!.view.superview else {return}
//make sure UIV honors safeAreaLayouts
setConstraints(vc: self, pc: parent)
}
A button within the child, setController, dismisses itself:
@objc func buttonAction(sender: UIButton!) {
self.willMove(toParent: nil)
self.removeFromParent()
self.view.removeFromSuperview()
self.dismiss(animated: false, completion: nil)
}
Everything works great the first time I call up the child UIView. It curls down while covering the first/parent UIVIEW, etc. etc. Figure 1 But after I dismiss the child view and call it again, the child view scrolls down without really covering the main view, it's like a mishmash. Figure 2 Only after all is said and done, then the child view covers everything.
So am curious if I am dismissing something incorrectly.
At the very bottom is my code where MainController initiates a subview called setController. The new subview is created when I click the button
However, within setController's code I get back a nil when I try to the superview:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("\(self.view.superview)" ?? "count->no parent")
}
I am assigning the second view as a subview, but obviously I am missing something. Have I misunderstood how UIView hierarchy works?
class MainController: UIViewController {
private lazy var setController = SetController()
var invButton : MyButton!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
invButton = makeButton(vControl: self, btype: ButtType.inv, action: #selector(self.buttonAction(sender:)))
invButton.frame.origin.x = self.view.frame.width * 0.1
invButton.frame.origin.y = self.view.frame.height * 0.1
invButton.setTitle("Settings", for: .normal)
}
override var prefersStatusBarHidden: Bool {
return false
}
@objc func buttonAction(sender: UIButton!) {
guard let theButton = sender as? MyButton else { return}
UIView.transition(with: self.view, duration: 0.5, options: .transitionCurlDown, animations: { [self] in
self.addChild(setController)
self.view.addSubview(setController.view)
setController.didMove(toParent: self)
}, completion: nil)
}
}
Below is my code. I have the ViewController, which takes up entire screen (set background color, makes sure status bar is visible, etc.
It then calls up the MainController, which is set to be only in the safeAreaLayout frame. It has a button that brings up a third view controller when clicked.
Everything works, the ViewController covers the entire screen, the MainController rests within the safeAreaLayouts of the iPhone X, and the third view controller comes up the same size and position as the MainController.
It's that last part I want to make sure of, that that is the way it is supposed to come up. Can I count on that? Or must I set its frame myself to be sure?
ViewController
class ViewController: UIViewController {
var mainController = MainController()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.addChild(mainController)
self.view.addSubview(mainController.view)
setConstraints(vc: mainController, pc: view)
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = bgColor
}
override var prefersStatusBarHidden: Bool {
return false
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
}
func setConstraints (vc: UIViewController, pc: UIView) {
vc.view.translatesAutoresizingMaskIntoConstraints = false
var constraints = [NSLayoutConstraint]()
constraints.append(vc.view.leadingAnchor.constraint(equalTo: pc.safeAreaLayoutGuide.leadingAnchor))
constraints.append(vc.view.trailingAnchor.constraint(equalTo: pc.safeAreaLayoutGuide.trailingAnchor))
constraints.append(vc.view.bottomAnchor.constraint(equalTo: pc.safeAreaLayoutGuide.bottomAnchor))
constraints.append(vc.view.topAnchor.constraint(equalTo: pc.safeAreaLayoutGuide.topAnchor))
NSLayoutConstraint.activate(constraints)
}
MainController
class MainController: UIViewController {
private lazy var countController = CountController()
var invButton : MyButton!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
...button code ....
}
override var prefersStatusBarHidden: Bool {
return false
}
@objc func buttonAction(sender: UIButton!) {
guard let theButton = sender as? MyButton else { return}
self.addChild(countController)
self.view.addSubview(countController.view)
}
}
ThirdViewController
class CountController : UIViewController {
var backButton : MyButton!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .gray
}
}
When my app starts up I have my ViewController, which automatically creates my MainScreen (also a view controller). Right after
self.addChild(mainController)
I call a function which sets my constraints
func setConstraints (vc: UIViewController) {
vc.view.translatesAutoresizingMaskIntoConstraints = false
var constraints = [NSLayoutConstraint]()
constraints.append(vc.view.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor))
constraints.append(vc.view.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor))
constraints.append(vc.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor))
constraints.append(vc.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor))
NSLayoutConstraint.activate(constraints)
}
All is fine up to this point, the MainScreen is bound by the top and bottom safe areas.
At some point from MainScreen I create another UIViewController.
countController.modalPresentationStyle = .fullScreen
self.present(countController, animated: true, completion: {})
Yet, no matter how hard I try to apply the constraints to the new controller, I crash with the following msg:
Unable to activate constraint with anchors <NSLayoutXAxisAnchor....because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal."
Am too new to figure out where my error is.
I have my mainController (parent) and my menuController (child).
I call the menuController with
addChild(child)
view.addSubview(child.view)
child.didMove(toParent: self)
The child dismisses itself with:
self.dismiss(animated: true, completion: nil)
The question I have, is how do I clean up the child within the parent? Surely I have to do something?
So am watching a Speech To Text demo on YouTube, here:
https://www.youtube.com/watch?v=SZJ8zjMGUcY
There are no files, so am typing from the screen, and immediately run into an error that confuses me.
at
class ViewController : UIViewController, SFSpeechRecognizer {
here's a screenshot:
Swift gives me an error indicating that Multiple Inheritance is not allowed.
The programmer doesn't have files to download, and I like to start from scratch anyway, typing and copying so I am forced to read each line.
Is there something I have to change in the project itself that allows Multiple Inheritances?
This video is from last year, and is on Swift 5.0. So I don't think there could be that much of a major change in Swift in that time.
Thanks
So sorry if I should't be asking this here, but am trying to find a current-ish tutorial on how to make an app that converts speech to text in real time.
Transcribing from text to speech as you're speaking.
I've found a few one's on YouTube, but they are quite old, or just transcribing from a recorded file, etc. etc.
If anyone is aware of a good tutorial, paid or not, I would so appreciate any link.
Thank you
While I do need to get another HD, I currently have
34.85 GB (12.61 GB purgeable) available.
Yet for some reason when I try to run update on Xcode, it says I don't have enough HD space. That's three times the final size of the new Xcode.
Is there some way around this?
Below is a simple code patch I use to create a custom button, am new at this. I noticed the text does not appear and am wondering what the proper method is for making the text appear?
func makeButton (vControl: ViewController, action: Selector) {
let myButtonImage = UIImage(named: "Picture1.png")
let imageScale = myButtonImage!.size.width / myButtonImage!.size.height
let wwidth = vControl.self.view.bounds.width
let button = CreateButton(frame: CGRect(x: 100, y: 100, width: (myButtonImage?.size.width)!/3, height: (myButtonImage?.size.height)!/3))
button.setImage(myButtonImage, for: .normal)
button.backgroundColor = .clear
button.setTitleColor(.black, for: .normal)
button.setTitle("Test Button", for: .normal)
button.addTarget(vControl, action: action, for: .touchUpInside)
vControl.view.addSubview(button)
button.center = vControl.view.center
}