Stopping all sounds at once? - objective-c

Hello
I have 16 sounds in a view. And they loops etc. I want a rect button where you tap it all the sounds stop.
Here is the code i used for one of the sounds, its the same for the rest.#
- (IBAction)twoSound:(id)sender; {
if (twoAudio && twoAudio.playing) {
[twoAudio stop];
[twoAudio release];
twoAudio = nil;
return;
}
NSString *path = [[NSBundle mainBundle] pathForResource:#"2" ofType:#"wav"];
if (twoAudio) [twoAudio release];
NSError *error = nil;
twoAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (error)
NSLog(#"%#",[error localizedDescription]);
twoAudio.delegate = self;
[twoAudio play];
}
I tried
-(IBAction)goStop:(id)sender; {
[oneAudio, twoAudio, threeAudio, fourAudio, fiveAudio, sixAudio, sevenAudio, eightAudio, nineAudio, tenAudio, elevenAudio, twelveAudio, thirteenAudio, fourteenAudio, fifthteenAudio, sixteenAudio stop];
}
But that didnt work.
Thanks

I think you have to use an NSArray instead of many sound objects. So you can easily fill the array with the 12 sounds and then you can use a "for" cycle to stop them all.

Related

freeing memory in a simple avaudioengine program?

I'm wondering how to free memory in this simple program that plays a file through a buffer and then stops it.
-(void)setupAudioOne
{
NSError *error;
BOOL success = NO;
_player = [[AVAudioPlayerNode alloc] init];
NSURL *hiphopOneURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Hip Hop 1" ofType:#"caf"]];
AVAudioFile *hiphopOneFile = [[AVAudioFile alloc] initForReading:hiphopOneURL error:&error];
_playerLoopBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:[hiphopOneFile processingFormat] frameCapacity:(AVAudioFrameCount)[hiphopOneFile length]];
success = [hiphopOneFile readIntoBuffer:_playerLoopBuffer error:&error];
_engine = [[AVAudioEngine alloc] init];
[_engine attachNode:_player];
AVAudioMixerNode *mainMixer = [_engine mainMixerNode];
AVAudioFormat *stereoFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:44100 channels:2];
[_engine connect:_player to:mainMixer fromBus:0 toBus:0 format:stereoFormat];
[self startEngine];
}
Above is the general setup of the engine and the player node.
Then we implement the player with a play button:
- (IBAction)play:(id)sender {
if (!self.playerIsPlaying)
{
[self setupAudioOne];
[_player scheduleBuffer:_playerLoopBuffer atTime:nil options:AVAudioPlayerNodeBufferLoops completionHandler:nil];
[_player play];
}
}
And finally we stop the player with a stop button:
- (IBAction)stopHipHopOne:(id)sender {
if (self.playerIsPlaying) {
[_player stop];
}
playerIsPlaying is just a simple BOOL that determines if the _player is playing.
So basically my question is, when you hit the stop button as this program is written now, no memory will be freed.
Surely there is a simple line of code that I can add to the stop button that frees up the memory the engine and player is using?
Any thoughts?
Yes, there is. After stopping the player node, you can call:
[_engine disconnectNodeInput:_player];
[_engine detachNode:_player];
I saw you're also keeping a reference to the audio buffer, so you might want to nil that one as well. Let me know if that doesn't work for you. Something else could be leaking.

NSString set from a url doesn't read?

I am having trouble getting my NSString to read my string that I have set. The play action is hooked to a UIButton OnTouchDown if it matters.
- (IBAction)play {
if (audioPlayer.playing == NO) {
urlSong = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/k.mp3", [[NSBundle mainBundle] resourcePath]]];
[audioPlayer release];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlSong error:&error];
audioPlayer.numberOfLoops = 0;
//if i set this line to stringSong = #"k"; then comment out the next line everything works fine
stringSong = [[urlSong lastPathComponent] stringByDeletingPathExtension];
label.text = stringSong;
AVAudioSession *audiosession = [AVAudioSession sharedInstance];
[audiosession setCategory:AVAudioSessionCategoryAmbient error:nil];
[audioPlayer play];
[start setTitle:#"Stop" forState:UIControlStateNormal];
}
else
if ([stringSong isEqualToString:#"k"]){
label.text = #"audio stopped";
[audioPlayer stop];
}
}
When I run the code on my iPhone Xcode returns
EXC_BAD_ACCESS
on this line
if ([stringSong isEqualToString:#"k"]){
I know this is due to me trying to set the string from the url because when I plainly set my string to 'k' the code executes just fine.
If anybody is wondering the overall point of this, I am trying to have my audio buttons set to stop all other audio when this button is pressed and start the audio assigned to this button which in this case is 'k.mp3'. But if this audio is already playing just to stop playing all audio. Thank you.
You aren't retaining stringSong.
This line:
stringSong = [[urlSong lastPathComponent] stringByDeletingPathExtension];
Should be:
stringSong = [[[urlSong lastPathComponent] stringByDeletingPathExtension] retain];
At some point this needs to be released.

Parsing a .csv file from a server with Objective-C

I have looked for an answer of a long time and still not found one so I thought I'd ask the question myself.
In my iPad app, I need to have the capability of parsing a .csv file in order to populate a table. I am using http://michael.stapelberg.de/cCSVParse to parse the csv files. However, I have only been successful in parsing local files. I have been trying to access a file from a server but am getting nowhere.
Here is my code to parse a local .csv file:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
//UITextField *reply = [alertView textFieldAtIndex:buttonIndex];
NSString *fileName = input.text;
NSLog(#"fileName %#", fileName);
CSVParser *parser = [CSVParser new];
if ([fileName length] != 0)
{
NSString *pathAsString = [[NSBundle mainBundle]pathForResource:fileName ofType:#"csv"];
NSLog(#"%#", pathAsString);
if (pathAsString != nil)
{
[parser openFile:pathAsString];
NSMutableArray *csvContent = [parser parseFile];
NSLog(#"%#", csvContent);
[parser closeFile];
NSMutableArray *heading = [csvContent objectAtIndex:0];
[csvContent removeObjectAtIndex:0];
NSLog(#"%#", heading);
AppDelegate *ap = [AppDelegate sharedAppDelegate];
NSManagedObjectContext *context = [ap managedObjectContext];
NSString *currentHeader = [heading objectAtIndex:0];
NSString *currentValueInfo = [heading objectAtIndex:1];
NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:#"Field" inManagedObjectContext:context];
[newObject setValue:#"MIS" forKey:#"header"];
[newObject setValue:currentHeader forKey:#"fieldName"];
for (NSArray *current in csvContent)
{
NSManagedObject *newField = [NSEntityDescription insertNewObjectForEntityForName:#"Field" inManagedObjectContext:context];
[newField setValue:currentHeader forKey:#"header"];
[newField setValue:currentValueInfo forKey:#"valueInfo"];
NSLog(#"%#", [current objectAtIndex:0]);
[newField setValue:[current objectAtIndex:0] forKey:#"fieldName"];
[newField setValue:[NSNumber numberWithDouble:[[current objectAtIndex:1] doubleValue]] forKey:#"value"];
}
NSError *error;
if (![context save:&error])
{
NSLog(#"Couldn't save: %#", [error localizedDescription]);
}
[self storeArray];
[self.tableView reloadData];
}
}
}
input.text = nil;
}
Forgive the weird beginning and ending brace indentation. :/
Anyway, so that is my code to take input from a user and access a file locally which I'm sure you guys have realized already. Now I want to know how to get the path of a file in my server.
Also if you guys see anything else wrong such as writing style and other bad habits please tell me as I'm new to iOS.
Thank you so much in advance! If you didn't understand my question please clarify as I'm bad at explaining myself at times! :)
As I am guessing you are trying to get data from a server's .csv file and want to show that data in table view list.
so I suggest you try to get that .csv file data in NSData and then work on that.
NSData *responseData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"serverUrl"]];
NSString *csvResponseString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] autorelease];
NSLog(#"responseString--->%#",csvResponseString);
Now try to use nsstring's method (componentsSeparatedByString) with coma (')
arrSepratedData = [[responseString componentsSeparatedByString:#","];
Now use this arr for UITableView data populate.

AVAudioPlayer how to play fast or slow file

I just need to listen to the file slowly or quickly. Any help will be greatly appreciated
AVAudioplayer can't do that, AVPlayer can.
// play audio file as NSURL *url;
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:url options:options];
NSString *tracksKey = #"tracks";
[urlAsset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:tracksKey] completionHandler:
^{
// Completion handler block.
dispatch_async(dispatch_get_main_queue(),
^{
NSError *error = nil;
AVKeyValueStatus status = [urlAsset statusOfValueForKey:tracksKey error:&error];
if (status == AVKeyValueStatusLoaded) {
self.avPlayer = [AVPlayer playerWithPlayerItem:playerItem];
[avPlayer play];
avPlayer.rate = 0.5;
}
else {
// You should deal with the error appropriately.
NSLog(#"The asset's tracks were not loaded:\n%#", [error localizedDescription]);
}
});
}];
thanks but I have solved it as follows:
Install cocos2d http://www.cocos2d-iphone.org/download
[[SimpleAudioEngine sharedEngine] playEffect: (NSString *) pitch (float32) pan (float32) gain (float32)]
its simple and works....
in Swift 3.0 it will be like this -
audioP = try! AVAudioPlayer(contentsOf: URL(fileURLWithPath: selectedPath), fileTypeHint: "caf")
audioP.enableRate = true
audioP.prepareToPlay()
audioP.rate = 1.5
audioP.play()
Hope this helps :)

QTMovie not playing in new window

I have a MAC OSX application in which I would like to press a button in the main window and open a new window in which a movie is played. This is my IBAction code;
- (IBAction) playButtonClicked: (id) sender
{
MoviePlayerController *moviePlayerWindow = [[MoviePlayerController alloc] initWithWindowNibName:#"MoviePlayer"];
[moviePlayerWindow showWindow:self];
NSError *error;
NSString *moviePath = [[NSBundle mainBundle] pathForResource:#"sample_iTunes" ofType:#"mov"];
QTMovie *movie = [QTMovie movieWithFile:moviePath error:&error];
if (error) {
NSLog(#"%#", [error localizedDescription]);
} else {
[movie gotoBeginning];
[moviePlayerWindow.movieViewer setMovie:movie];
[moviePlayerWindow.movieViewer play:nil];
}
}
movieViewer is a QTMovieViewer outlet inside the new window.
The window opens but no movie is played; can someone understand what I am doing wrong ? I can send the complete project (it is a test one, very small) if needed.
Try changing NSError *error; to NSError *error = nil;