iPhone Subclass of Sounds - iphone

Update! Fixed! This now works! Use at your will !
#import <Foundation/Foundation.h>
#import "AVFoundation/AVAudioPlayer.h"
#interface SoundsClass : NSObject <AVAudioPlayerDelegate> {
AVAudioPlayer *buttonClick;
AVAudioPlayer *slide;
AVAudioPlayer *Cellpush;
AVAudioPlayer *pop;
AVAudioPlayer *tick;
AVAudioPlayer *done;
AVAudioPlayer *swoosh;
}
#property (nonatomic, retain) AVAudioPlayer *buttonClick;
#property (nonatomic, retain) AVAudioPlayer *slide;
#property (nonatomic, retain) AVAudioPlayer *Cellpush;
#property (nonatomic, retain) AVAudioPlayer *pop;
#property (nonatomic, retain) AVAudioPlayer *tick;
#property (nonatomic, retain) AVAudioPlayer *done;
#property (nonatomic, retain) AVAudioPlayer *swoosh;
-(void)PlayButtonClick:(id)sender;
-(void)PlaySlide:(id)sender;
-(void)PlayCellPush:(id)sender;
-(void)PlayPop:(id)sender;
-(void)PlayTick:(id)sender;
-(void)PlayDone:(id)sender;
-(void)PlaySwoosh:(id)sender;
#end
#import "SoundsClass.h"
#implementation SoundsClass
#synthesize buttonClick, swoosh, slide, tick, done, Cellpush, pop;
-(void)dealloc{
[buttonClick release];
[swoosh release];
[slide release];
[tick release];
[done release];
[Cellpush release];
[pop release];
[super dealloc];
}
-(void)PlayButtonClick:(id)sender{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:#"appSounds"]) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"button_click"
ofType:#"caf"];
self.buttonClick = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL
fileURLWithPath:path] error:NULL];
self.buttonClick.delegate = self;
[self.buttonClick play];
}
}
-(void)PlaySlide:(id)sender{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:#"appSounds"]) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"popover_show" o
fType:#"caf"];
slide = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]
error:NULL];
slide.delegate = self;
[slide play];
}
}
-(void)PlayCellPush:(id)sender{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:#"appSounds"]) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"cell_swoosh"
ofType:#"caf"];
buttonClick = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL
fileURLWithPath:path] error:NULL];
buttonClick.delegate = self;
[buttonClick play];
}
}
-(void)PlayPop:(id)sender{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:#"appSounds"]) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"pop" ofType:#"caf"];
buttonClick = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL
fileURLWithPath:path] error:NULL];
buttonClick.delegate = self;
[buttonClick play];
}
}
-(void)PlayTick:(id)sender{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:#"appSounds"]) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"Tick" ofType:#"caf"];
buttonClick = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL
fileURLWithPath:path] error:NULL];
buttonClick.delegate = self;
[buttonClick play];
}
}
-(void)PlayDone:(id)sender{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:#"appSounds"]) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"Done" ofType:#"caf"];
buttonClick = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL
fileURLWithPath:path] error:NULL];
buttonClick.delegate = self;
[buttonClick play];
}
}
-(void)PlaySwoosh:(id)sender{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:#"appSounds"]) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"flip" ofType:#"caf"];
buttonClick = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL
fileURLWithPath:path] error:NULL];
buttonClick.delegate = self;
[buttonClick play];
}
}
#end
When you want to use the class just
#import "SoundsClass.h"
#class SoundsClass;
SoundsClass *sounds;
#property (nonatomic, retain) SoundsClass *sounds;
-(IBAction)openFolder:(id)sender;
-(IBAction)openFolder:(id)sender{
sounds = [[SoundsClass alloc] init];
[self.sounds PlayButtonClick:sender];
}
Thats about it really easy but works with Defaults just use a switch and set bool

Related

Play multiple music with AVAudioPlayer

I am trying to play a 2 musics they should play after each other with loop option ,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString * music = [[NSBundle mainBundle] pathForResource:#"music" ofType:#"wav"];
myMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
myMusic.delegate = self;
[myMusic play];
}
and play second music :
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
NSString * music = [[NSBundle mainBundle] pathForResource:#"music2" ofType:#"wav"];
myMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
myMusic.delegate = self;
[myMusic play];
NSLog(#"MUSIC FINISH");
}
now the problem is how can I play previous music ?
Try this
ViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController : UIViewController<AVAudioPlayerDelegate>
{
AVAudioPlayer *player;
int nIndex;
NSArray *arrPlayList;
}
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
arrPlayList =[[NSArray alloc]initWithObjects:#"music1.wav",#"music2.wav",#"music3.wav", nil];
nIndex =[arrPlayList count]-1;
[self playSound:nIndex];
}
-(void)playSound:(int )index
{
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *strFilePath = [path stringByAppendingPathComponent:[arrPlayList objectAtIndex:index]];
NSURL *filePath = [NSURL fileURLWithPath:strFilePath];
player= [[AVAudioPlayer alloc] initWithContentsOfURL:filePath error:nil];
player.delegate=self;
[player play];
}
#pragma mark - AVFoundation Delegate Methods
-(void)audioPlayerDidFinishPlaying: (AVAudioPlayer *)player successfully:(BOOL)flag
{
NSLog(#"MUSIC FINISH");
if (nIndex==0) {
return;
}
nIndex--;
[self playSound:nIndex];
}
-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{
NSLog(#"Decode Error occurred");
}

ios AVAudioPlayer plays sound with echo

I have two AVAudioPlayer to determine what sound has finished to do something after that. the first sound plays just fine but the second sound (twoPlayer) plays the sound with echo. any of you knows why or how this happend?
I have this on my .h file:
#interface myClass : UIViewController<AVAudioPlayerDelegate>
{
AVAudioPlayer *onePlayer;
AVAudioPlayer *twoPlayer;
}
#property (retain, nonatomic) AVAudioPlayer *onePlayer;
#property (retain, nonatomic) AVAudioPlayer *twoPlayer;
.m file:
NSString *urlAddress = [[NSBundle mainBundle] pathForResource:#"sound" ofType:#"m4a"];
NSURL *url = [NSURL fileURLWithPath:urlAddress];
NSError *error;
twoPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
twoPlayer.delegate=self;
twoPlayer.volume=0.5;
if (twoPlayer == nil)
NSLog(#"[error description]");
else
[twoPlayer play];
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
if (player==onePlayer) {
[onePlayer release];
}
if (player==twoPlayer) {
[numberPlayer release];
}
}
I found the error I was setting a UIButton with "forControlEvents:UIControlEventAllTouchEvents" and the actionw was been trigger more then once. I replace the UIButton with this forControlEvents:UIControlEventTouchDown and works just fine.

iOS : How to avoid overlapping sound/music in PickerViewController

I have one music player with multiple sounds using picker view. My problem is when i click the next music, the previous one will overlap with the one that i've selected.Meaning when i scroll the pickerview to select a new object, it will play a new music/sound but the previous object will overlap the current selection. I want to stop the previous music so that it won't overlap. Here is the code.
H File :
#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>
#interface PickerViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource, AVAudioPlayerDelegate>{
UIPickerView *picker;
UILabel *musicTitle;
NSMutableArray *musicList;
AVAudioPlayer *audioPlayer;
}
#property (nonatomic, retain) IBOutlet UIPickerView *picker;
#property (nonatomic, retain) IBOutlet UILabel *musicTitle;
#property (nonatomic, retain) NSMutableArray *musicList;
-(IBAction)playSelectedMusic:(id)sender;
#end
M File :
- (void)viewDidLoad
{
[super viewDidLoad];
musicList = [[NSMutableArray alloc] initWithObjects:#"m1",#"m2",#"m3",#"m6",#"m4", #"m5",nil];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if ([[musicList objectAtIndex:row] isEqual:#"m1"])
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"m1" ofType:#"mp3"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
pickerView.delegate = self;
[theAudio play];
[theAudio setCurrentTime:0.0]; (our friend from this forum have suggested this but still doens't work)
NSString *resultString = [[NSString alloc] initWithFormat:
#"m1",
[musicList objectAtIndex:row]];
musicTitle.text = resultString;
}
if ([[musicList objectAtIndex:row] isEqual:#"m2"])
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"m2" ofType:#"mp3"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
pickerView.delegate = self;
[theAudio play];
[theAudio setCurrentTime:0.0]; (our friend from this forum have suggested this but still doens't work)
NSString *resultString = [[NSString alloc] initWithFormat:
#"m2",
[musicList objectAtIndex:row]];
musicTitle.text = resultString;
}
Code amendment :
NSString *path = [[NSBundle mainBundle] pathForResource:#"you" ofType:#"mp3"];
NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:file error:NULL];
[file release];
self.audioPlayer = theAudio;
[theAudio release];
[audioPlayer prepareToPlay];
[audioPlayer setDelegate:self];
[audioPlayer setNumberOfLoops:0];
[audioPlayer stop];
my silly mistake :
#property (nonatomic, retain) AVAudioPlayer *audioPlayer;
Just stop the currently playing sound before starting another one, your AVAudioPlayer is an ivar so you could do it. Add
[theAudio stop];

iphone piano app doesnt play notes as expected

Im making a piano test app, all the keyboard is sounding now playing notes that I've recorded using garage band, but I have some problems:
-the notes are 5 seconds long (minimum time of garage band), so a note cannot be repeated, I have to wait until the actual note about 1 sec sound and then silence for about 4 sec,
also sometimes notes cannot be played as expected,
Im using AVFoundation.framework,,
tried with AudioToolbox.framework, but it gives problems with my 4.1 ipod touch (doesnt work!!) but in the simulator looks fine
I also checked OpenAL, and ObjectAL, but seem a bit to much for just playing notes??
here the code
#import "pianoViewController.h"
#implementation pianoViewController
#synthesize myMusic;
#synthesize myMusic2;
#synthesize myMusic3;
#synthesize myMusic4;
#synthesize myMusic5;
#synthesize myMusic6;
#synthesize myMusic7;
#synthesize myMusic8;
#synthesize myMusic9;
#synthesize myMusic10;
#synthesize myMusic11;
#synthesize myMusic12;
-(IBAction)Play{
[myMusic play];
}
-(IBAction)Play2{
[myMusic2 play];
}
.
.
.
- (void)viewDidLoad {
NSString *pathToMusicFile = [[NSBundle mainBundle] pathForResource:#"c3" ofType:#"aif"];
myMusic = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile] error:NULL];
myMusic.delegate = self;
myMusic.numberOfLoops = 0;
myMusic.volume = 1.0;
NSString *pathToMusicFile2 = [[NSBundle mainBundle] pathForResource:#"c#" ofType:#"aif"];
myMusic2 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile2] error:NULL];
myMusic2.delegate = self;
myMusic2.numberOfLoops = 0;
myMusic2.volume = 1.0;
NSString *pathToMusicFile3 = [[NSBundle mainBundle] pathForResource:#"d" ofType:#"aif"];
myMusic3 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile3] error:NULL];
myMusic3.delegate = self;
myMusic3.numberOfLoops = 0;
myMusic3.volume = 1.0;
//[super viewDidLoad];
NSString *pathToMusicFile4 = [[NSBundle mainBundle] pathForResource:#"d#" ofType:#"aif"];
myMusic4 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile4] error:NULL];
myMusic4.delegate = self;
myMusic4.numberOfLoops = 0;
myMusic4.volume = 1.0;
//[super viewDidLoad];
NSString *pathToMusicFile5 = [[NSBundle mainBundle] pathForResource:#"e" ofType:#"aif"];
myMusic5 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile5] error:NULL];
myMusic5.delegate = self;
myMusic5.numberOfLoops = 0;
myMusic5.volume = 1.0;
NSString *pathToMusicFile6 = [[NSBundle mainBundle] pathForResource:#"f" ofType:#"aif"];
myMusic6 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile6] error:NULL];
myMusic6.delegate = self;
myMusic6.numberOfLoops = 0;
myMusic6.volume = 1.0;
NSString *pathToMusicFile7 = [[NSBundle mainBundle] pathForResource:#"f#" ofType:#"aif"];
myMusic7 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile7] error:NULL];
myMusic7.delegate = self;
myMusic7.numberOfLoops = 0;
myMusic7.volume = 1.0;
NSString *pathToMusicFile8 = [[NSBundle mainBundle] pathForResource:#"g" ofType:#"aif"];
myMusic8 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile8] error:NULL];
myMusic8.delegate = self;
myMusic8.numberOfLoops = 0;
myMusic8.volume = 1.0;
NSString *pathToMusicFile9 = [[NSBundle mainBundle] pathForResource:#"g#" ofType:#"aif"];
myMusic9 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile9] error:NULL];
myMusic9.delegate = self;
myMusic9.numberOfLoops = 0;
myMusic9.volume = 1.0;
NSString *pathToMusicFile10 = [[NSBundle mainBundle] pathForResource:#"a" ofType:#"aif"];
myMusic10 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile10] error:NULL];
myMusic10.delegate = self;
myMusic10.numberOfLoops = 0;
myMusic10.volume = 1.0;
NSString *pathToMusicFile11 = [[NSBundle mainBundle] pathForResource:#"a#" ofType:#"aif"];
myMusic11 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile11] error:NULL];
myMusic11.delegate = self;
myMusic11.numberOfLoops = 0;
myMusic11.volume = 1.0;
NSString *pathToMusicFile12 = [[NSBundle mainBundle] pathForResource:#"b" ofType:#"aif"];
myMusic12 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile12] error:NULL];
myMusic12.delegate = self;
myMusic12.numberOfLoops = 0;
myMusic12.volume = 1.0;
[super viewDidLoad];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
- (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 {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
So is there a way so that i can use AVFoundation to play multiple notes quickly? (almost overlapping like with AudioToolbox)
or what do you suggest?
thank you!
Instead of shoe-horning in a fix for something that shouldn't be a problem, I suggest instead that you use some audio editing software that does not have a minimum track length restriction.
One such example, which is Mac compatible and free, is Audacity: http://audacity.sourceforge.net/
Also, OpenAL is perfect for playing lots of short sounds, potentially overlapping. I think you can have 32 playing at once if you like.

Bug in AVAudioPlayer class?

I'll keep it short and sweet - I'm building an application just for practice before I buy myself the iPhone Developer Program.
I'm experimenting with the AVFoundation.framework and I keep running into a bug which will only let me play the first sound I initialize in my code. Do you think any of you could help me out? Thanks in advance!! :)
view controller
-(IBAction)play {
if (segments.selectedSegmentIndex == 0) {
NSLog(#"Segment = 0");
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:#"meow" ofType:#"wav"];
if (path != nil) {
NSURL *url = [NSURL fileURLWithPath:path];
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:NULL];
[player prepareToPlay];
[player play];
}
}
else if (segments.selectedSegmentIndex == 1) {
NSLog(#"Segment = 1");
NSBundle *bundle = [NSBundle mainBundle];
NSString *path2 = [bundle pathForResource:#"meowloud" ofType:#"wav"];
if (path2 != nil) {
NSURL *url2 = [NSURL fileURLWithPath:path2];
AVAudioPlayer *player2 = [[AVAudioPlayer alloc]initWithContentsOfURL:url2 error:NULL];
[player2 prepareToPlay];
[player2 play];
// [player2 release];
}
}
text1.textColor = [UIColor clearColor];
text2.textColor = [UIColor clearColor];
text3.textColor = [UIColor clearColor];
text4.textColor = [UIColor clearColor];
}
When this code gets executed, only the meow.wav is executed, no matter which segment is selected.
Your code has a couple of memory leaks. You allocate instances of AVAudioPlayer in your play method, but you never release those instances. See Cocoa's memory management qguidelines for details. Since the AVAudioPlayer instances need to remain in memory to play, the easiest solution is to add a member variable to your viewController class and set it up as a retain property.
For the sake of Don't Repeat Yourself (DRY), I would also suggest adding a method which encapsulates all of the code needed to play a single wav file.
Here is how I would write this view controller:
MyViewController.h
#interface MyViewController : UIViewController
{
AVAudioPlayer *player;
}
#property(nonatomic, retain) AVAudioPlayer *player;
- (void)playWavFile:(NSString *)fileName;
- (IBAction)play;
#end
MyViewController.m
#synthesize player;
- (void)dealloc {
[player release];
}
- (void)playWavFile:(NSString *)fileName {
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:fileName ofType:#"wav"];
if (path != nil) {
AVAudioPlayer *newPlayer;
NSURL *url = [NSURL fileURLWithPath:path];
newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url
error:NULL];
[self setPlayer:newPlayer];
[newPlayer release];
[newPlayer prepareToPlay];
[newPlayer play];
}
}
- (IBAction)play {
if (segments.selectedSegmentIndex == 0) {
[self playWavFile:#"meow"];
}
else if (segments.selectedSegmentIndex == 1) {
[self playWavFile:#"meowloud"];
}
}