Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development > iPhone SDK Development - Advanced Discussion

Reply
 
LinkBack Thread Tools Display Modes
Old 02-05-2011, 08:51 AM   #1 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 19
JJSaccolo is on a distinguished road
Default Play an mp3 and disable the UIButton

Hi!
my app has this feature: the user can write (in an UITextfield) the numbers from 0 to 9 and, based on what he writes, the iPhone play a different mp3.

i've used AVFoundation framework and this is the code:

"my_class.h"

Code:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>

@interface my_class : UIViewController <AVAudioPlayerDelegate> {
	AVAudioPlayer *player;
	UIButton *playbutton;
	UITextField *textfield;
}

@property (nonatomic, retain) AVAudioPlayer *player;
@property (nonatomic, retain) IBOutlet UIButton *playbutton;
@property (nonatomic, retain) IBOutlet UITextField *textfield;

-(IBAction)play;

and "my_class.m"

Code:
#import "my_class.h"
@implementation my_class
@synthesize playbutton, textfield, player;

-(IBAction)play{
        NSString *text = textfield.text;
	int x = [text length];
	
	if (x!=0){

		playbutton.enabled = NO;
		for (int i=0; i<x; i++){
			switch ([text characterAtIndex: i]) {
				case '0':{
					NSString *path = [[NSBundle mainBundle] pathForResource:@"0" ofType:@"mp3"];
					NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
					AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
					[file release];
					self.player = p;
					[p release];
					[player prepareToPlay];
					[player setDelegate:self];
					[self.player play];
					usleep(1000000);
				}
                                         break;
				case '1':{
					NSString *path = [[NSBundle mainBundle] pathForResource:@"1_ITA" ofType:@"mp3"];
					NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
					AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
					[file release];
					self.player = p;
					[p release];
					[player prepareToPlay];
					[player setDelegate:self];
					[self.player play];
					usleep(600000);				
				}
					break;
                                //here other cases: 2,3,4,5,6,7,8,9
                                default:{
					usleep(100000);
				}
					break;
			}	
		}
		self.playbutton.enabled = YES;
	}
	
}

So, it works! If the user write "0123" the iphone play 0.mp3, 1.mp3, 2.mp3 and 3.mp3!

the problem is that when the user push the UIButton, this UIButton remains pressed (in blue, do you understand?) until the last mp3 is played!
The problem is that when it is blue, it doesn't become disable (with self.playbutton.enabled = NO), and if the user push again, it starts the IBAction again!

I've tried to write "self.playbutton.hidden = YES" (instead of enable = NO) and the UIButton become hidden only when the last mp3 is played (or, better, only when the switch finish)!

The problem is that the command line is before the switch!

What do you suggest?
JJSaccolo is offline   Reply With Quote
Old 02-05-2011, 05:48 PM   #2 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

The cause of the problem is that when you call usleep, UIKit does not have a chance to change the state of your button. Your function needs to return before anything in the UI can change.

The best way to do this would be to store the sounds to be played into an NSMutableArray, start the first one, and use the AVAudioPlayerDelegate methods to know when each song has finished. When each one finishes, you would remove it from the array and start the next one. When they are all done, you could re-enable the button.

I don't have any code handy to help with this, but the documentation should be enough to get you started if you want to try this.
JasonR is offline   Reply With Quote
Old 02-06-2011, 04:12 AM   #3 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 19
JJSaccolo is on a distinguished road
Default

Quote:
Originally Posted by JasonR View Post
The cause of the problem is that when you call usleep, UIKit does not have a chance to change the state of your button. Your function needs to return before anything in the UI can change.
oh! thanks!
it's strange because i've tried one thing like this:

Code:
-(IBAction)play{
   playbutton.enable = NO;
   [self play2];
}

-(void)play2{
   //here the code, then
   playbutton.enable = YES;
   return;
}
but nothing change!

Quote:
Originally Posted by JasonR View Post
The best way to do this would be to store the sounds to be played into an NSMutableArray, start the first one, and use the AVAudioPlayerDelegate methods to know when each song has finished. When each one finishes, you would remove it from the array and start the next one. When they are all done, you could re-enable the button.

I don't have any code handy to help with this, but the documentation should be enough to get you started if you want to try this.
ok perfect, i'll try!
thank you very much!!
JJSaccolo is offline   Reply With Quote
Old 02-06-2011, 11:41 AM   #4 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

Quote:
Originally Posted by JJSaccolo View Post
oh! thanks!
it's strange because i've tried one thing like this:

Code:
-(IBAction)play{
   playbutton.enable = NO;
   [self play2];
}

-(void)play2{
   //here the code, then
   playbutton.enable = YES;
   return;
}
This code has the same problem. By the time the UI has a chance to update you've already set enable back to YES already. So the UI never sees that you set it to NO.

Using the delegate methods should work much better.
JasonR is offline   Reply With Quote
Old 02-06-2011, 04:32 PM   #5 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 19
JJSaccolo is on a distinguished road
Default

Quote:
Originally Posted by JasonR View Post
This code has the same problem. By the time the UI has a chance to update you've already set enable back to YES already. So the UI never sees that you set it to NO.

Using the delegate methods should work much better.
thanks angain

this metod should works

Code:
-(void)audioDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)completed
one more (maybe) stupid question: why is better use an NSMutableArray?
Because i'm reading the numbers that the user writes in the UITextField using
Code:
for (int i=0; i<lenght; i++){
[text characterAtIndex: i] 
...
}
isn't enough?
JJSaccolo is offline   Reply With Quote
Old 02-06-2011, 05:40 PM   #6 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

Well, you won't be able to do it from inside a for loop. But you could just add the index (I would call it something more descriptive than just "i") to your .h and keep track of it each time an audio sound ends.
JasonR is offline   Reply With Quote
Old 02-07-2011, 09:20 AM   #7 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 19
JJSaccolo is on a distinguished road
Default

SOLVED!

this is the code:

my_class.h
Code:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>

@interface italiano : UIViewController <AVAudioPlayerDelegate> {
	AVAudioPlayer *player;
	UIButton *playbutton;
	UITextField *textfield;
	NSMutableArray *array;
	
}

@property (nonatomic, retain) AVAudioPlayer *player;
@property (nonatomic, retain) IBOutlet UIButton *playbutton;
@property (nonatomic, retain) IBOutlet UITextField *textfield;
@property (nonatomic, retain) NSMutableArray *array;

-(IBAction)play;
-(void)play2;
@end
and "my_class.m"

Code:
-(IBAction)play{
	self.playbutton.enabled = NO;
	array = [[NSMutableArray alloc]init];
	NSString *testo = textfield.text;
	NSString *uppercase = [testo uppercaseString];
	int x = [uppercase length];
	if (x!=0){
		for (int i=0; i<x; i++){
			[array insertObject:[NSString stringWithFormat:@"%c", [uppercase characterAtIndex:i]] atIndex:i];
		}
		[self play2];
	}
}

 -(void)play2{
	 NSString *carattere = [NSString stringWithFormat:@"%@", [array objectAtIndex:0]];
	 NSString *path;
	 if ([carattere isEqualToString:@"0"]){
		 path = [[NSBundle mainBundle] pathForResource:@"0" ofType:@"mp3"];
	}
        //here if carattere == 1, 2, 3..., 9
	 NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
	 AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
	 [file release];
	 self.player = p;
	 [p release];
	 [player prepareToPlay];
	 [player setDelegate:self];
	 [self.player play];
}

- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully: (BOOL) completed {
	int count = [array count];
	if (count == 1){
		self.playbuttonita.enabled = YES;
	}
	else {
		[array removeObjectAtIndex:0];
		[self play];
	}
}
thanks you very very very much

now i have only one more question (sorry!!): why the first time that i press the UIButton, it takes a little bit of time to play? and just the first time!
I mean... the uibutton remains pressed for 1/2 seconds, the it starts to play... after that, it works normally.
Do you know why?

by the way, thanks again

EDIT: i found this, maybe it can help me! http://www.iphonedevsdk.com/forum/ip...h-latency.html

Last edited by JJSaccolo; 02-07-2011 at 10:14 AM.
JJSaccolo is offline   Reply With Quote
Old 02-07-2011, 10:50 AM   #8 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

Glad to hear you got it working. One thing I've seen is that the simulator seems to add a long delay that does not happen on the device. If it's happening on the device, the thread you linked to looks like it has everything I would try next.
JasonR is offline   Reply With Quote
Reply

Bookmarks

Tags
avaudioplayer, avfoundation, enable, play mp3, uibutton

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 403
16 members and 387 guests
Brandt, coolman, fredidf, Free App Monster, givensur, iAppDeveloper, jbro, Kryckter, locombiano89, Mah6447, Meoz, simplymuzik3, SLIC, stevenkik, Tomsky, WeaselPig
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,646
Threads: 94,111
Posts: 402,862
Top Poster: BrianSlick (7,990)
Welcome to our newest member, locombiano89
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 05:51 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0