Changing advice language doesn't work - ios

I'm new with Skobbler SDK and learn with the Swift Demo + the well documented tuto (http://developer.skobbler.com/getting-started/ios#sec01)
However, I still can't configure the advice language settings using their instructions ...
Here is my code :
let settings = SKAdvisorSettings()
settings.advisorVoice = "fr"
settings.language = SKAdvisorLanguage.FR
settings.advisorType = SKAdvisorType.AudioFiles
settings.resourcesPath = NSBundle.mainBundle().resourcePath! + "/SKMaps.bundle/AdvisorConfigs/Languages"
The event is define by :
func routingService(routingService: SKRoutingService!, didChangeCurrentAdvice currentAdvice: SKRouteAdvice!, isLastAdvice: Bool) {
NSLog("New advice "+currentAdvice.adviceInstruction)
}
Si I get "in 90 meters turn right " for instance.
By the way, no audio files are played neither
Could you please give me a hand :) ? Thank you in advance

There is a bug in the code that is supposed to "play the audio advice" (in AudioService.m) - the name of the .mp3 file was not correctly built.
I've fixed this by making the following change:
func playAudioFile(audioFileName: String) {
var soundFilePath: String = audioFilesFolderPath + "/" + audioFileName
soundFilePath = soundFilePath + ".mp3"
if !NSFileManager.defaultManager().fileExistsAtPath(soundFilePath)
{
return
}
else
{
audioPlayer = try? AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: soundFilePath), fileTypeHint: nil)
audioPlayer.delegate = self
audioPlayer.play()
}
}
This affected only the swift demo and will be fixed in the next update

Ok I found my mistake by replacing :
settings.advisorType = SKAdvisorType.AudioFiles
with
settings.advisorType = SKAdvisorType.TextToSpeech
However I still don't know how to use prerecorded files ... Even with the section "Using prerecorded files in tuto ...

Did you set your settings as the advisorConfigurationSettings of your SKRoutingService?
[SKRoutingService sharedInstance].advisorConfigurationSettings = advisorSettings;
You will also have to set the path for the audio files like this:
NSBundle* advisorResourcesBundle = [NSBundle bundleWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"SKAdvisorResources.bundle"]];
NSString* soundFilesFolder = [advisorResourcesBundle pathForResource:#"Languages" ofType:#""];
NSString* audioFilesFolderPath = [NSString stringWithFormat:#"%#/%#/sound_files",soundFilesFolder,userLanguageCode];
[AudioService sharedInstance].audioFilesFolderPath = audioFilesFolderPath;
userLanguageCode would be "fr" in your case

Related

AudiKit AKPitchShifter & AKTimePitch Pitch Correction

I'm trying to get an autotune like sound from AKPitchShifter but the most I get is chipmunk type sound. I've played with different combinations with the AKTimePitch.pitch and the AKPitchShifter.shift both individually and together but everything comes out squeaky and too robotic.
I'm new to this library. Is there anything that I can add, such as other AudioKit classes, to get the sound close to autotune.
do {
let file = try AKAudioFile(readFileName: "someones-voice.wav")
let player = try AKAudioPlayer(file: file)
player.looping = true
let timePitch = AKTimePitch(player)
timePitch.pitch = 0.5
AKManager.output = timePitch
let pitchShifter = AKPitchShifter(player)
pitchShifter.shift = 1.5
AKManager.output = pitchShifter
try AKManager.start()
player.play()
} catch {
print(error.localizedDescription)
}
Resolved in git through a pull request addressing a few errors: https://github.com/lsamaria/AutoTuneSampler/pull/3

Converting Objective-C block to Swift

I have a function written in Objective-C below and I want to convert it to Swift, but I keep getting errors.
Below is the Objective-C code:
- (void)openFileWithFilePathURL:(NSURL*)filePathURL
{
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL];
self.filePathLabel.text = filePathURL.lastPathComponent;
//
// Plot the whole waveform
//
self.audioPlot.plotType = EZPlotTypeBuffer;
self.audioPlot.shouldFill = YES;
self.audioPlot.shouldMirror = YES;
//
// Get the audio data from the audio file
//
__weak typeof (self) weakSelf = self;
[self.audioFile getWaveformDataWithCompletionBlock:^(float **waveformData,
int length)
{
[weakSelf.audioPlot updateBuffer:waveformData[0]
withBufferSize:length];
}];
}
And here is my Swift code:
func openFileWithFilePathURL(url: NSURL) {
let audioFile = EZAudioFile(URL: url)
audioPlot.plotType = EZPlotType.Buffer
audioPlot.shouldFill = true
audioPlot.shouldMirror = true
audioFile.getWaveformDataWithCompletionBlock({(waveformData, length) in
audioPlot.updateBuffer(waveformData[0], withBufferSize: length)
})
}
And I always get the error
Command failed due to signal: Segmentation fault: 11
I'm new to iOS language and I spent hours on this problem. I really have no clue on how to fix this problem.
I guess the problem lies in how I converted the block from Objective-C to Swift.
Thank you for your help!!
You can try this:
func openFileWithFilePathURL(filePathURL: NSURL) {
self.audioFile = EZAudioFile.audioFileWithURL(filePathURL)
self.filePathLabel.text = filePathURL.lastPathComponent
//
// Plot the whole waveform
//
self.audioPlot.plotType = EZPlotTypeBuffer
self.audioPlot.shouldFill = true
self.audioPlot.shouldMirror = true
//
// Get the audio data from the audio file
//
weak var weakSelf = self
self.audioFile.getWaveformDataWithCompletionBlock({(waveformData: Float, length: Int) -> Void in
weakSelf.audioPlot.updateBuffer(waveformData[0], withBufferSize: length)
})
}
This is typically an Xcode glitch. The only thing you can do it try to alter the syntax, first by the order of the lines and then the actual lines themselves (i.e. the type of line has several variations). You can also submit a bug report to apple if you can still not fix it. (here)

PHAsset get original file name

I wonder if there any way to get the original file name using PHAsset?
I use the following code to extract the file info.
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:requestOption resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
entity.fileUrl = [info objectForKey:#"PHImageFileURLKey"];
entity.filename = [[NSFileManager defaultManager] displayNameAtPath:[ entity.fileUrl path]];
}];
However, It doesn't return original name but the name in the format "img_123"
I've just checked official apple docs . there has been introduced a new class PHAssetResource and the property originalFilename which is available in the iOS 9+. The problem is that I use the image picker library CTAssetsPickerController which 's based on the Photos framework; it returns picked image as the PHAsset object . PS. I'm looking for the solution which is compatible with iOS 8 :).
Thank you!
On iOS 8 your solution is the right (and only approach) to get a filename at all.
On iOS 9 this works:
NSArray *resources = [PHAssetResource assetResourcesForAsset:asset];
NSString *orgFilename = ((PHAssetResource*)resources[0]).originalFilename;
Short way to get file name with one line of code. Asset have a property for accessing file name.
NSString*FileName=[asset valueForKey:#"filename"];
NSLog(#"File name %#",FileName);
Its done.
Note: Accepted answer takes lots of time to load a phasset but it works.
I had to modify my code because it started returning nonsense names. My solution was to pick the resource based on asset's mediaType and resource's type, but maybe there is something easier:
extension PHAsset {
var primaryResource: PHAssetResource? {
let types: Set<PHAssetResourceType>
switch mediaType {
case .video:
types = [.video, .fullSizeVideo]
case .image:
types = [.photo, .fullSizePhoto]
case .audio:
types = [.audio]
case .unknown:
types = []
#unknown default:
types = []
}
let resources = PHAssetResource.assetResources(for: self)
let resource = resources.first { types.contains($0.type)}
return resource ?? resources.first
}
var originalFilename: String {
guard let result = primaryResource else {
return "file"
}
return result.originalFilename
}
}
Maybe you can use the method, it works above iOS8:
[asset requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
CIImage *fullImage = [CIImage imageWithContentsOfURL:contentEditingInput.fullSizeImageURL];
NSLog(#"%#",contentEditingInput.fullSizeImageURL);//get url
NSLog(#"%#", fullImage.properties.description);//get {TIFF}, {Exif}
}];
#holtmann solution written in Swift
let resource = PHAssetResource.assetResources(for: asset)
let filename = resource.first?.originalFilename ?? "unknown"

how to check if file exist use swift, rewrite from objective c

how to rewrite this objective-c language to swift?
NSString *filePath = #"/Applications/MySample.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// avoid open add friend
}
regards.
Equivalent Swift 3 Code:
let filePath = "/Applications/MySample.app"
if (FileManager.default.fileExists(atPath: filePath)) {
// avoid open add friend
}
Swift 2
let filePath = "/Applications/MySample.app"
if (NSFileManager.defaultManager().fileExistsAtPath(filePath))
{
// avoid open add friend
}
Some years after the question has been asked I recommend to take rewrite literally and use the URL related API
let fileURL = URL(fileURLWithPath:"/Applications/MySample.app")
if let _ = try? fileURL.checkResourceIsReachable() {
// file exists
}
let path = "/Applications/MySample.app"
let hasFile = FileManager().fileExists(atPath: path)
if hasFile {
// use file
}
else {
// possibly inform user the file does not exist
}

Load file in Today extension when device is locked

In my today extension with my device unlocked, this line of code works as expected, returning the data from the image path:
let imageData = NSData(contentsOfFile: path)
However when my device is locked with a passcode, it returns nil. Is there any way to access images in the file system when the device is locked? I can access UserDefaults just fine, but not files in the directory for my shared group. Here is how I am creating the path, calling imagePath, which is correctly populated with the path I expect in both cases:
func rootFilePath() -> String? {
let manager = NSFileManager()
let containerURL = manager.containerURLForSecurityApplicationGroupIdentifier(GROUP_ID)
if let unwrappedURL = containerURL {
return unwrappedURL.path
}
else {
return nil
}
}
func imagePath() -> String? {
let rootPath = rootFilePath()
if let uPath = rootPath {
return "\(uPath)/\(imageId).png"
}
else {
return nil
}
}
I just figured it out! You need to set the file permissions accordingly:
NSFileManager *fm = [[NSFileManager alloc] init];
NSDictionary *attribs = #{NSFileProtectionKey : NSFileProtectionNone};
NSError *unprotectError = nil;
BOOL unprotectSuccess = [fm setAttributes:attribs
ofItemAtPath:[containerURL path]
error:&unprotectError];
if (!unprotectSuccess) {
NSLog(#"Unable to remove protection from file! %#", unprotectError);
}
In many cases you wouldn't normally want to do this, but because the information is intended to be viewed from the lock screen, I'm OK with removing file protection.

Resources