AVMIDIPlayer DLSBankManager::AddBank: Bank load failed - midi

When I use AVMIDIPlayer to play a MusicSequence with only one note message. Most of times it works fine but sometimes it has no sound and logged as below:
DLSBankManager::AddBank: Bank load failed
Error Domain=com.apple.coreaudio.avfaudio Code=-10871 "(null)"
It works well on iOS9, but when i test it on iOS10 it runs into this issue.
I'm sure that the sf2 sound bank file url is set properly.
I paste the code as below:
func playAVMIDIPlayerPreview(_ musicSequence:MusicSequence) {
guard let bankURL = Bundle.main.url(forResource: "FluidR3 GM2-2", withExtension: "sf2") else {
fatalError("soundbank file not found.")
}
var status = OSStatus(noErr)
var data:Unmanaged<CFData>?
status = MusicSequenceFileCreateData (musicSequence,
MusicSequenceFileTypeID.midiType,
MusicSequenceFileFlags.eraseFile,
480, &data)
if status != OSStatus(noErr) {
print("bad status \(status)")
}
if let md = data {
let midiData = md.takeUnretainedValue() as Data
do {
try self.midiPlayerPreview = AVMIDIPlayer(data: midiData, soundBankURL: bankURL)
} catch let error as NSError {
print("Error \(error)")
}
data?.release()
self.midiPlayerPreview?.play({ () -> Void in
self.midiPlayerPreview = nil
self.musicSequencePreview = nil
})
}
}
The error is occur on this line:
try self.midiPlayerPreview = AVMIDIPlayer(data: midiData, soundBankURL: bankURL)

Try setting the global variable errno to 0 errno = 0 before loading the soundfont with
try self.midiPlayerPreview = AVMIDIPlayer(data: midiData, soundBankURL: bankURL)
We experienced the same issue and at the same time this one.
So we tried to apply the fix of the other issue to this one and it just worked.

Related

stopContinuousRecognition() blocks the app for 5-7 seconds

I am trying to implement speech recognition using the Azure Speech SDK in iOS project using Swift and I ran into the problem that the speech recognition completion function (stopContinuousRecognition()) blocks the app UI for a few seconds, but there is no memory or processor load or leak. I tried to move this function to DispatchQueue.main.async {}, but it gave no results. Maybe someone faced such a problem? Is it necessary to put this in a separate thread and why does the function take so long to finish?
Edit:
It is very hard to provide working example, but basically I am calling this function on button press:
private func startListenAzureRecognition(lang:String) {
let audioFormat = SPXAudioStreamFormat.init(usingPCMWithSampleRate: 8000, bitsPerSample: 16, channels: 1)
azurePushAudioStream = SPXPushAudioInputStream(audioFormat: audioFormat!)
let audioConfig = SPXAudioConfiguration(streamInput: azurePushAudioStream!)!
var speechConfig: SPXSpeechConfiguration?
do {
let sub = "enter your code here"
let region = "enter you region here"
try speechConfig = SPXSpeechConfiguration(subscription: sub, region: region)
speechConfig!.enableDictation();
speechConfig?.speechRecognitionLanguage = lang
} catch {
print("error \(error) happened")
speechConfig = nil
}
self.azureRecognition = try! SPXSpeechRecognizer(speechConfiguration: speechConfig!, audioConfiguration: audioConfig)
self.azureRecognition!.addRecognizingEventHandler() {reco, evt in
if (evt.result.text != nil && evt.result.text != "") {
print(evt.result.text ?? "no result")
}
}
self.azureRecognition!.addRecognizedEventHandler() {reco, evt in
if (evt.result.text != nil && evt.result.text != "") {
print(evt.result.text ?? "no result")
}
}
do {
try! self.azureRecognition?.startContinuousRecognition()
} catch {
print("error \(error) happened")
}
}
And when I press the button again to stop recognition, I am calling this function:
private func stopListenAzureRecognition(){
DispatchQueue.main.async {
print("start")
// app blocks here
try! self.azureRecognition?.stopContinuousRecognition()
self.azurePushAudioStream!.close()
self.azureRecognition = nil
self.azurePushAudioStream = nil
print("stop")
}
}
Also I am using raw audio data from mic (recognizeOnce works perfectly for first phrase, so everything is fine with audio data)
Try closing the stream first and then stopping the continuous recognition:
azurePushAudioStream!.close()
try! azureRecognition?.stopContinuousRecognition()
azureRecognition = nil
azurePushAudioStream = nil
You don't even need to do it asynchronously.
At least this worked for me.

Error validating CMS signature

For the past 2 weeks I've been banging my head against a wall trying to create and validate CMS signatures in Swift 4 using OpenSSL. My code is ultimately destined to be run on Linux, so I can't use the macOS Security framework. I believe I have finally gotten CMS signature creation working properly. My code for that looks like this:
let testBundle = Bundle(for: type(of: self))
guard let textUrl = testBundle.url(forResource: "test_message", withExtension: "txt"),
let signingKeyUrl = testBundle.url(forResource: "signing_key", withExtension: "pem"),
let signingCertUrl = testBundle.url(forResource: "signing_cert", withExtension: "pem") else {
exit(1)
}
let certFileObject = signingCertUrl.path.withCString { filePtr in
return fopen(filePtr, "rb")
}
defer {
fclose(certFileObject)
}
let keyFileObject = signingKeyUrl.path.withCString { filePtr in
return fopen(filePtr, "rb")
}
defer {
fclose(keyFileObject)
}
guard let key = PEM_read_PrivateKey(keyFileObject, nil, nil, nil),
let cert = PEM_read_X509(certFileObject, nil, nil, nil) else {
exit(1)
}
OpenSSL_add_all_ciphers()
OpenSSL_add_all_digests()
OPENSSL_add_all_algorithms_conf()
guard let textData = FileManager.default.contents(atPath: textUrl.path) else {
exit(1)
}
guard let textBIO = BIO_new(BIO_s_mem()) else {
print("Unable to create textBIO")
exit(1)
}
_ = textData.withUnsafeBytes({dataBytes in
BIO_write(textBIO, dataBytes, Int32(textData.count))
})
guard let cms = CMS_sign(cert, key, nil, textBIO, UInt32(CMS_BINARY)) else {
exit(1)
}
When I debug this code, I see that the cms object is being set after the CMS_sign call, so I believe that the signature was generated properly. Right after this, I'm trying to validate the signature I just created. That code looks like this:
let store = X509_STORE_new()
X509_STORE_add_cert(store, cert)
let outBIO = BIO_new(BIO_s_mem())
let result = CMS_verify(cms, nil, store, nil, outBIO, 0)
print("result : \(result)")
if result != 1 {
let errorCode: UInt = ERR_get_error()
print("ERROR : \(String(format: "%2X", errorCode))")
}
When I run this code, however, result == 0, indicating an error. The error code that OpenSSL is returning is 0x2E099064. I ran this command:
openssl errstr 0x2E099064
Which gave me this info about the error:
error:2E099064:CMS routines:func(153):reason(100)
After a bit more digging, I think that the error corresponds to PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH. I got that from the pkcs7.h file here. I'm not 100% that this is the correct error message, however.
My question is, why is my signature validation failing? I'm using the exact same certificate to validate the signature. All of this code is inline, so nothing is getting lost anywhere. Can any of you give me an idea where things are going wrong?

File couldn’t be opened because you don’t have permission to view it error

I have Googled and poked around Stack Overflow and can't seem to find a solution for this. I have:
let fileURL = URL( string: "file:///Users/me/file.txt" )
var rawDataString: String
var errorString: String?
do {
rawDataString = try String( contentsOf: fileURL!, encoding: String.Encoding.utf8 )
} catch let error as NSError {
errorString = error.description
print( errorString! )
return
}
and it's erroring out with
Error Domain=NSCocoaErrorDomain Code=257 "The file “file.txt” couldn’t
be opened because you don’t have permission to view it."
Permissions are read for all users:
$ ls -al file.txt
-rw-r--r--# 1 me staff 348306 Dec 13 2016 file.txt
Any ideas would be most welcome.
Anyone coming across this thread, #LeoDabus pointed me to where to turn off sandbox, which worked:
He also cleaned up my code a bit:
let fileURL = URL( fileURLWithPath: "/Users/me/file.txt" )
var rawDataString: String
var errorString: String?
do {
rawDataString = try String( contentsOf: fileURL, encoding: .utf8 )
} catch let error as NSError {
errorString = error.description
rawDataString = ""
return
}
(For iOS)
Sadly #Dribbler´s answer didn't work for me because I didn't have App Sandbox enabled and it still didn't work. In my case I used the UIDocumentPickerViewController and I was unable to access the file.
Adding url.startAccessingSecurityScopedResource() before working with the file resolved the issue for me.
Here is an example of the didPickDocumentsAt delegate function from a UIDocumentPickerViewController:
guard let url = urls.first else {
return
}
guard url.startAccessingSecurityScopedResource() else { // Notice this line right here
return
}
do {
let data = try Data(contentsOf: url)
} catch let error {
print(error.localizedDescription)
}
After adding that line it worked for me.
I actually was not able to get the preferred answers above to work for me in swift playground.
Another solution is just to create a command line app in Xcode. Then paste the above and it should work fine.

Upload Image to Amazon S3 Using Swift3

After looking around at different threads such as these (Swift - AWS S3 Upload Image from Photo Library and download it), and (Upload image AWS S3 bucket in swift), I got pretty close to getting an image upload to work but can't figure out what I'm doing wrong?
I get the following error below in my console.
Error: Error Domain=com.amazonaws.AWSS3TransferUtilityErrorDomain Code=1 "(null)" UserInfo={Server=AmazonS3, Transfer-Encoding=Identity, Connection=close, Content-Type=application/xml, Date=Tue, 13 Dec 2016 05:58:32 GMT, x-amz-request-id=2A76DF0FE33476C5, x-amz-id-2=QWZgOETbWQfddlqKmm0w3Z9HFGM2x1DWnrFjukiajTsIXfbSt9W0orTkoZeNXH/bI1xfc3mxI4Q=, x-amz-bucket-region=us-west-1}
My code is below:
let myIdentityPoolId = "us-west-2:dca2beb4-etcetcetc...."
let credentialsProvider:AWSCognitoCredentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.usWest2, identityPoolId: myIdentityPoolId)
let configuration = AWSServiceConfiguration(region: AWSRegionType.usWest2, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
I then call to upload my image with a function I made below
func uploadImage(filename:String){
print("AWS Upload Image Attempt...")
//defining bucket and upload file name
let S3BucketName: String = "distribution-tech-mobile"
let filepath = "\(AppDelegate.appDelegate.applicationDocumentsDirectory())/\(filename)"
let imageURL = URL(fileURLWithPath: filepath)
let S3UploadKeyName = filename //TODO: Change this later
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest?.bucket = S3BucketName
uploadRequest?.key = filename
uploadRequest?.contentType = "image/jpeg"
uploadRequest?.body = imageURL
uploadRequest?.serverSideEncryption = AWSS3ServerSideEncryption.awsKms
uploadRequest?.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
DispatchQueue.main.async(execute: {
self.amountUploaded = totalBytesSent // To show the updating data status in label.
self.fileSize = totalBytesExpectedToSend
print("\(totalBytesSent)/\(totalBytesExpectedToSend)")
})
}
self.uploadCompletionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
if ((error) != nil){
print("Failed with error")
print("Error: \(error!)");
}
else{
print("Sucess")
}
})
}
let transferUtility = AWSS3TransferUtility.default()
let expression = AWSS3TransferUtilityUploadExpression()
transferUtility.uploadFile(imageURL, bucket: S3BucketName, key: S3UploadKeyName, contentType: "image/jpeg", expression: expression, completionHander: uploadCompletionHandler).continue({ (task) -> AnyObject! in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let exception = task.exception {
print("Exception: \(exception.description)")
}
if let _ = task.result {
print("Upload Starting!")
}
return nil;
})
}
I get the console message "Upload Starting" and then a message "Failed with error" (which comes from my completion handler), followed by the error I assume from Amazon.
Any thoughts on what I'm doing wrong?
Okay I found the answer, but I have a different problem now that I'll post in another question regarding showing upload progress.
The answer was my bucket was created in the incorrect region. I created my credentials in Oregon, which is Us-West-2, and I created the bucket in Northern California by accident the first time. This apparently created the error.

Alamofire download in MacOS. Looks fine, progresses is working, but no file?

I have Alamofire added through cocoapods and I have a method going to download a zip file (approx 50Mb).
While downloading everything looks perfect. I can see in Activity Monitor that 50Mb is downloaded for my app, I can see the progressbar zinging across. But I can never find the file.
Right now I have it set to use the current directory, but have tried others just in case. I have even searched the entire drive by data modified and never find anything.
Here is my code.
func downloadAndInstall(){
log.info("Downloading and Installing.....")
displayToUser(content: "Downloading and Installing.....")
let urlString = updatePackageURL //(This is http://xxxx.com/xxxxpackage.zip)
let fileManager = FileManager.default
currentDir = fileManager.currentDirectoryPath
let fileURL: URL = URL(string: currentDir + "/package.zip")!
let destination: DownloadRequest.DownloadFileDestination = { _, _ in (fileURL, []) }
log.info("FILEURL: \(fileURL)")
var progressValues: [Double] = []
var response: DefaultDownloadResponse?
Alamofire.download(urlString, to: destination)
.downloadProgress { progress in
progressValues.append(progress.fractionCompleted)
log.info("Latest Progress Value: \(progress.fractionCompleted)")
self.progBar.doubleValue = progress.fractionCompleted
}
.response { resp in
response = resp
if progressValues.last != 1.0 {
//backout of the process, something went wrong
log.debug("Something went wrong downloading the file. Close and try again.")
self.displayToUser(content: "Something went wrong downloading the file. Close and try again.")
self.exitpoorly()
}
else{
log.info("Download Finished")
self.displayToUser(content: "Download Finished")
self.extractpackage()
}
}
var previousProgress: Double = progressValues.first ?? 0.0
for progress in progressValues {
previousProgress = progress
}
if let lastProgressValue = progressValues.last {
log.info("Current Download Value: \(lastProgressValue, 1.0)")
} else {
//Fail
}
}
I'd suggest checking for any errors, e.g.:
Alamofire.download(urlString, to: destination)
.downloadProgress { progress in
...
}
.response { response in
guard response.error == nil else {
//backout of the process, something went wrong
log.debug("Something went wrong downloading the file. Close and try again.")
log.debug(response.error!.localizedDescription)
...
self.exitpoorly()
return
}
log.info("Download Finished")
...
}
Maybe the app is sandboxed, or perhaps you don't have permissions for that folder. It's hard to say without seeing the error.