AudioKit rolling waveform plot not displaying on physical device - objective-c

I have been experimenting with AudioKit and have made a sample app to try and plot recording audio and audio from playback. I am seeing an issue though, when I record or playback audio, the rolling waveform doesn't show up in the view on a device. It shows up perfectly fine on sim (11.4) however. I've provided the recording view controller code below for context in how I'm trying to implement this while recording audio.
Any help or being pointed in the general direction would be greatly appreciated.
RecordingVC.m code:
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setupConfig];
[self setupUI];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) setupUI
{
//Configure waveform view
self.recordingPlotView.gain = 2;
self.recordingPlotView.backgroundColor = [UIColor colorWithRed: .10 green: .10 blue: .10 alpha: 1];
self.recordingPlotView.color = [UIColor colorWithRed: .44 green: .44 blue: .44 alpha: 1];
self.recordingPlotView.plotType = EZPlotTypeRolling;
self.recordingPlotView.shouldFill = YES;
self.recordingPlotView.shouldMirror = YES;
[self.view addSubview: self.recordingPlotView];
}
- (void) setupConfig
{
self.isRecording = NO;
[AKSettings setAudioInputEnabled: true];
[AKSettings setPlaybackWhileMuted: true];
[AVAudioSession.sharedInstance setCategory: AVAudioSessionCategoryAmbient withOptions: kAudioSessionProperty_OverrideCategoryDefaultToSpeaker error: nil];
self.mic = [[EZMicrophone alloc] initWithMicrophoneDelegate: self];
}
#pragma mark - EZMicrophone Delegate methods
- (void) microphone:(EZMicrophone *)microphone
hasAudioReceived:(float **)buffer
withBufferSize:(UInt32)bufferSize
withNumberOfChannels:(UInt32)numberOfChannels
{
__weak typeof (self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.recordingPlotView updateBuffer:buffer[0]
withBufferSize:bufferSize];
});
}
- (void) microphone:(EZMicrophone *)microphone
hasBufferList:(AudioBufferList *)bufferList
withBufferSize:(UInt32)bufferSize
withNumberOfChannels:(UInt32)numberOfChannels
{
if (self.isRecording)
{
[self.recorder appendDataFromBufferList:bufferList
withBufferSize:bufferSize];
}
}
#pragma mark - EZRecorder Delegate methods
- (void)recorderDidClose:(EZRecorder *)recorder
{
self.recorder.delegate = nil;
}
#pragma mark - Utils
- (NSArray *)applicationDocuments
{
return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
}
- (NSString *)applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
- (NSURL *)testFilePathURL
{
return [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%#",
[self applicationDocumentsDirectory],
#"test2.m4a"]];
}
#pragma mark - user Interaction
- (IBAction)playButtonTapped:(id)sender {
if (self.isRecording)
{
self.isRecording = NO;
self.playButton.titleLabel.text = #"Record";
[self.mic stopFetchingAudio];
}
else
{
self.isRecording = YES;
self.playButton.titleLabel.text = #"Pause";
[self.mic startFetchingAudio];
self.recorder = [EZRecorder recorderWithURL: [self testFilePathURL] clientFormat: [self.mic audioStreamBasicDescription] fileType: EZRecorderFileTypeM4A delegate: self];
}
}
- (IBAction)stopButtonTapped:(id)sender {
if (self.isRecording)
{
self.isRecording = NO;
self.playButton.titleLabel.text = #"Record";
[self.mic stopFetchingAudio];
[self.recorder closeAudioFile];
}
[self.recordingPlotView clear];
self.recorder = nil;
}
#end
RecordingVC.h code:
#import <UIKit/UIKit.h>
#import AudioKit;
#import AudioKitUI;
#interface FirstViewController : UIViewController <EZMicrophoneDelegate, EZRecorderDelegate>
#property (strong, nonatomic) IBOutlet EZAudioPlot *recordingPlotView;
#property (nonatomic, strong) EZMicrophone* mic;
#property (nonatomic, strong) EZRecorder* recorder;
#property (nonatomic, assign) BOOL isRecording;
#property (strong, nonatomic) IBOutlet UIButton *playButton;
#end
Small Update:
I've managed to get the playback waveform displaying on device by setting the gain in interface builder, even though I was setting it in code during viewDidLoad().
I've tried doing the same (setting the gain for the plot in interface builder) for the recording VC (the code above) but that did solve this as it did for the playback VC.

I ran your project and it works on the device the same as the simulator except that the simulator's microphone is the computer's and seems much more sensitive than on the device, so I had to set the gain higher:
self.recordingPlotView.gain = 20;
before I noticed the waveform.

Related

Watch Connectivity not working

I am trying to create an app where I can send information from an apple watch to my ios Parent App. I have written the code for it but when I run the WatchConnectivity App, the information does not transfer between the apple watch and the parent ios app. This may be a problem with my code or it may be because for some reason the watch does not start with the app. I have to go to the simulator and click on the app to get it started. Is this why my code is not working?
InterfaceController.m
#import "InterfaceController.h"
#import <WatchConnectivity/WatchConnectivity.h>
#interface InterfaceController() <WCSessionDelegate>
#property (strong, nonatomic) WCSession *session;
#end
#implementation InterfaceController
-(instancetype)init {
self = [super init];
if (self) {
if ([WCSession isSupported]) {
self.session = [WCSession defaultSession];
self.session.delegate = self;
[self.session activateSession];
}
}
return self;
}
- (IBAction)catPressed {
[self sendText:#"cat"];
}
- (IBAction)dogPressed {
[self sendText:#"dog"];
}
- (IBAction)pandaPressed {
[self sendText:#"panda"];
}
- (IBAction)bunnyPressed {
[self sendText:#"bunny"];
}
-(void)sendText:(NSString *)text {
NSDictionary *applicationDict = #{#"emoji":text};
[self.session updateApplicationContext:applicationDict error:nil];
}
ViewController.m
#import "ViewController.h"
#import <WatchConnectivity/WatchConnectivity.h>
#interface ViewController () <WCSessionDelegate>
#property (weak, nonatomic) IBOutlet UILabel *textLabel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
if ([WCSession isSupported]) {
WCSession *session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
NSLog(#"HIIII");
}
}
- (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext {
NSString *text = [applicationContext objectForKey:#"text"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.textLabel setText:[NSString stringWithFormat:#"Text: %#", text]];
});
}
It turns out that I needed to open the parent app on the iPhone first to start sharing information between the iPhone and Watch. Thanks to MSU_Bulldog for suggesting this idea.

Unbalanced calls to begin/end appearance transitions for <QLRemotePreviewContentController: 0x7d19a000> in UIDocumentInteraction

I am trying to load files in device by using UIDocumentInteractionController in a phonegap app. I have done by following.
#import <Foundation/Foundation.h>
#import <QuickLook/QuickLook.h>
#interface FileViewer : UIViewController <UIDocumentInteractionControllerDelegate>
#end
#implementation FileViewer
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (UIViewController *) documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {
return self;
}
- (void)viewDidLoad
{
[self viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
In Launcher.m i have done by following to show files:
CDVViewController* mainController = (CDVViewController*)[ super viewController ];
UIDocumentInteractionController *documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileLocation]];
FileViewer *vController = [[FileViewer alloc]init];
[mainController addChildViewController:vController];
documentInteractionController.delegate = vController;
[documentInteractionController presentPreviewAnimated:YES];
This result by giving error message:
"Presenting view controllers on detached view controllers is discouraged.
Unbalanced calls to begin/end appearance transitions for QLRemotePreviewContentController"
Thanks in advance!!
I have solved my issue by following way. It might not be the best way, so please suggest the best way also.
#interface Launcher : CDVPlugin<UIDocumentInteractionControllerDelegate>
#property (strong, nonatomic)UIViewController *navigatorController;
#property (strong, nonatomic)Launcher *launcher;
#property (strong, nonatomic)NSString *callbackId;
-(void)openFile:(CDVInvokedUrlCommand*)command;
#end
#import "Launcher.h"
#import "FileViewer.h"
#import<QuickLook/QuickLook.h>
#import <MobileCoreServices/MobileCoreServices.h>
#implementation Launcher
-(void)openFile:(CDVInvokedUrlCommand*)command{
CDVPluginResult *pluginResult = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSDictionary *params = [command.arguments objectAtIndex:0];
NSString *file = [params objectForKey:#"message"];
NSString *fileLocation = [documentsDirectory stringByAppendingFormat:#"/%#",file];
if (![fileLocation isEqual:[NSNull null]]) {
#try {
self.launcher = self;
CDVViewController *viewController = [CDVViewController new];
viewController.wwwFolderName = #"www";
viewController.startPage = #"main.html"; // page contains listview showing name of files
self.navigatorController = viewController;
UIDocumentInteractionController *documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileLocation]];
[[UIApplication sharedApplication].keyWindow setRootViewController:self.navigatorController];
documentInteractionController.delegate = self;
[documentInteractionController presentPreviewAnimated:YES];
}
#catch (NSException *exception) {
NSLog(#"dd : %#",[exception reason]);
}
}
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
- (UIViewController *)documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *)controller
{
return self.navigatorController;
}
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller
{
[[UIApplication sharedApplication].keyWindow setRootViewController:self.navigatorController];
self.launcher = nil;
}

How can i make a random sound array with objective c?

So i've done the tutorial where you code a button so that when you press it a sound plays. I'm trying to modify it so that when the button is pressed, a random sound plays.
here is the code:
viewcontroller.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#interface STViewController : UIViewController
- (IBAction)playAudio:(id)sender;
#property (nonatomic, strong) NSArray *sounds;
#end
viewcontroller.m
#import <AVFoundation/AVFoundation.h>
#import "STViewController.h"
#interface STViewController ()
#property (weak, nonatomic) IBOutlet UIButton *playAudio;
#end
#implementation STViewController
- (IBAction)playAudio:(id)sender {
AVAudioPlayer *audioPlayer;
NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"Woof" ofType:#"mp3"];
NSURL *audioURL = [NSURL fileURLWithPath:audioPath];
NSError *audioError = [[NSError alloc] init];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&audioError];
if (!audioError) {
[audioPlayer play];
NSLog(#"Woof!");
}
else {
NSLog(#"Error!");
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I've been dabbling with something along these lines
- (NSArray *)sounds
{
NSArray *sounds = [NSArray arrayWithObjects:
#"Woof.mp3",
#"Meow.mp3",
#"tweet.mp3",
#"Squeak.mp3",
#"Moo.mp3",
#"Croak.mp3",
#"Toot.mp3",
#"Quack.mp3",
#"Blub.mp3",
#"OWOwOw.mp3",
#"Fox.mp3",
nil];
return sounds;
}
but i'm not really sure how to make it random or even implement in in the code that I have going right now. Anyone have any ideas?
Just make it random try below:-
NSMutableArray *array=[NSMutableArray
arrayWithObjects:
#"Woof.mp3",
#"Meow.mp3",
#"tweet.mp3",
#"Squeak.mp3",
#"Moo.mp3",
#"Croak.mp3",
#"Toot.mp3",
#"Quack.mp3",
#"Blub.mp3",
#"OWOwOw.mp3",
#"Fox.mp3",
nil];
// now use exchangeobject with index api
int i=0;
for(i=0;i<=[array count]; i++)
{
NSInteger rand=(arc4random() %10);
[array exchangeObjectAtIndex:i
withObjectAtIndex:rand];
}

Why is Xcode saying my class implementation is incomplete?

I have created a singleton for my MusicBackground. And I receive a line code of imcomplete implementation of this line #implementation MyBgMusic. Can anyone tell me why ? Below is the code:
#import "MyBgMusic.h"
static MyBgMusic *sharedMyManager = nil;
#implementation MyBgMusic
#synthesize player,playBgMusic;
#pragma mark -
#pragma mark Singleton Methods
+ (MyBgMusic*)sharedInstance {
static MyBgMusic *_sharedInstance;
if(!_sharedInstance) {
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[super allocWithZone:nil] init];
});
}
return _sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
return [self sharedInstance];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
#if (!__has_feature(objc_arc))
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX; //denotes an object that cannot be released
}
- (id)autorelease {
return self;
}
- (void)dealloc
{
[MyBgMusic release];
[playBgMusic release];
[player release];
[super dealloc];
}
#endif
#pragma mark -
#pragma mark Custom Methods
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"music" ofType:#"mp3"];
self.player=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
player.delegate = self;
[player play];
player.numberOfLoops = -1;
[super viewDidLoad];
}
#end
For the M file, below is the code:
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAudioPlayer.h>
#interface MyBgMusic : UIViewController <AVAudioPlayerDelegate> {
AVAudioPlayer *player;
UIButton *playBgMusic;
}
#property (nonatomic, retain) IBOutlet AVAudioPlayer *player;
#property (nonatomic, retain) IBOutlet UIButton *playBgMusic;
+ (id)sharedManager;
-(IBAction) toggleMusic;
#end
And how do I reference to my toggle button: Below is the code :
- (IBAction)toggleMusic {
if ([self.player isPlaying] == YES) {
[self.player stop];
} else {
[self.player play];
}
self.playBgMusic.enabled = YES;
}
It means that your MyBgMusic class isn't doing everything it promised to do in its header file, which includes being a UIViewController and implementing the AVAudioPlayerDelegate protocol. I'm not familiar with exactly what the AVAudioPlayerDelegate is, but it's quite possible that your class doesn't implement all of the required methods.
Also, you're declaring methods +(id)sharedManager and -(IBAction)toggleMusic, but I don't see them anywhere in the implementation file. That would be a case of promising something in the header and not implementing it in the class.
It would help if you posted the actual error message.
That error means your #implementation section does not contain everything described in the #interface section.
I can see two problems.
First you need to place this code:
- (IBAction)toggleMusic {
...
}
Somewhere in between #implementation and #end.
And you also need to rename the line + (MyBgMusic*)sharedInstance to + (id)sharedManager.
EDIT:
To access the toggle music method elsewhere in your code, you would do:
[[MyBgMusic sharedManager] toggleMusic];
Your +(id)sharedManagerimplementation is called +(id)sharedInstance. Just guessing, but it seems they are supposed to do the same.

How to Change view(XIB) after imagePickerController:didFinishPickingMediaWithInfo?

I am new on iphone and objective-c development.
I want to know how i can change the view (XIB File) after the camera takes a picture.
Can anyone help me or share some code? I am searching for this since a week :(
After finishing the app, i am ready to share my project and/or make a tutorial.
Infos about my App: i want to scan barcodes and save the barcodes in my app.
For scanning barcodes iam using the ZBarSDK.
I hava a TabBarController, on the first Tab, i can open the camera.
After the scan process i want to jump to the second tab (another XIB File) and show the results.
Thanks for any help.
Here my code of the first tab (ScanCodeViewController):
.h
#import < UIKit/UIKit.h >
#class OutPutCodeViewController;
#interface ScanCodeViewController : UIViewController <ZBarReaderDelegate> {
IBOutlet UIImageView *img;
OutPutCodeViewController *output;
}
#property (nonatomic, retain) IBOutlet UIImageView *img;
#property (nonatomic, retain) OutPutCodeViewController *output;
- (IBAction) scanButton;
#end
.m
#import "ScanCodeViewController.h"
#implementation ScanCodeViewController
#synthesize img;
#synthesize output;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[img release];
[super dealloc];
}
- (IBAction) scanButton {
NSLog(#"Scanbutton wurde geklickt!");
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_I25 config: ZBAR_CFG_ENABLE to: 0];
[self presentModalViewController:reader animated: YES];
[reader release];
}
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
NSLog(#"Entered imagePickerController");
// ADD: get the decode results
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results) {
break;
}
img.image = [info objectForKey:UIImagePickerControllerOriginalImage];
[reader dismissModalViewControllerAnimated: YES];
//[self presentModalViewController:output animated:YES]; //by using this, app chrashes
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissModalViewControllerAnimated: YES];
}
#end
And here the Secong Tab (OutPutCodeViewController)
.h
#import <UIKit/UIKit.h>
#interface OutPutCodeViewController : UIViewController {
IBOutlet UIImageView *resultImage;
IBOutlet UITextField *resultText;
}
#property (nonatomic, retain) IBOutlet UIImageView *resultImage;
#property (nonatomic, retain) IBOutlet UITextField *resultText;
#end
.m
#import "OutPutCodeViewController.h"
#implementation OutPutCodeViewController
#synthesize resultImage;
#synthesize resultText;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[resultImage release];
[resultText release];
[super dealloc];
}
#end
Got it!
It is not possible to set more animate:YES.
Here is the sample and right code.
I hope it helps others.
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
break;
[reader dismissModalViewControllerAnimated: NO];
TableDetailViewController *tc = [[TableDetailViewController alloc] initWithNibName:#"TableDetailViewController" bundle:nil];
tc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:tc animated:YES];
[tc release];
}
brush51
In didFinishPickingMediaWithInfo you should call [self.tabBarController setSelectedIndex:1] to switch to the second tab.