I recording voice with AVAudioRecorder (with this tutorial http://www.tumblr.com/tagged/avaudiorecorder?before=1300075871 ) and then try to play recorded sound with CocosDenshion:
CDSoundEngine* soundEngine = [[CDSoundEngine alloc] init];
NSArray *defs = [NSArray arrayWithObjects: [NSNumber numberWithInt:1],nil];
[soundEngine defineSourceGroups:defs];
//......
[soundEngine loadBuffer:1 filePath:[recorder.url path]];
[soundEngine playSound:1 sourceGroupId:0 pitch:2.0f pan:0 gain:1.0f loop:NO];
This code works fine on simulator, but on device (iPad 2, iOS 5.1.1)- sound is not playing.
I'll try to play recorded sound with AVAudioPlayer - its playing fine, but I need to pitch sound and found thats using CocosDenshion is simplest way for that.
What settings or something other should I check or fix to play recorded sound?
Problem solved, first I've changed the way to create CDSoundEngine instance, to use CDAudioManager:
CDSoundEngine = [CDAudioManager sharedManager].soundEngine;
Then, before playing recorded sound set mode for CDAudioManager to kAMM_PlayAndRecord:
[CDAudionManager sharedManager] setMode:kAMM_PlayAndRecord];
And finally redirect AudioSession to speakerphone:
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof (audioRouteOverride),&audioRouteOverride);
and all worked fine.
Related
I'm using SpriteKit for my Mac OS project with Objective C and I'm trying to play a certain sound over and over again when contact between two nodes occurs. I don't want the player to wait for the sound to complete before playing it again. The sound is only about 1 second long, but it repeats as fast as every 0.5 seconds. I've tried two different methods and they both have issues. I'm probably not setting something up correctly.
Method #1 - SKAction
I tried getting one of the sprites to play the sound using the following code:
[playBarNode runAction:[SKAction playSoundFileNamed:#"metronome" waitForCompletion:NO]];
The sound plays perfectly on time, but the sound is modified. It sounds like reverb (echo) was applied to it and it has lost a lot of volume as well.
Method #2 - AVAudioPlayer
Here's the code I used to set this up:
-(void) initAudio {
NSString *path = [NSString stringWithFormat:#"%#/metronome.mp3", [[NSBundle mainBundle] resourcePath]];
NSURL *metronomeSound = [NSURL fileURLWithPath:path];
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:metronomeSound error:nil];
[_audioPlayer prepareToPlay];
}
Later on in code it is called like this:
[_audioPlayer play];
The issue with this one is that it seems to wait until it's completed playing the first time before playing the sound again. Basically it fails to play many times.
Am I setting this up incorrectly? How can I fix this? Thanks in advance.
Retry method 1, but instead of having the sprite play the sound, have the scene play the sound via
[self runAction:[SKAction playSoundFileNamed:#"metronome" waitForCompletion:NO]];
inside the game SKScene class
I have a short method which plays an audio notification using the AudioToolbox/AudioServices library (i've removed most of the functional code for brevity):
- (IBAction)thatWasEasy:(id)sender {
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:#"easy" ofType:#"mp3"];
NSURL *aFileURL = [NSURL fileURLWithPath:filePath isDirectory:NO];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridge_retained CFURLRef)aFileURL, &soundID) ;
AudioServicesPlaySystemSound(soundID);
}
The audio plays correctly in the simulator as well as on iPad 1 and iPad 2 devices, however on the iPad 3 (Verizon LTE version) the sound is not heard. I've checked the devices sound settings thoroughly, and also converted the audio file type to wav, and caf with no difference in behavior.
Any suggestions on troubleshooting this a bit deeper? I unfortunately do not have another iPad 3 lying around for comparison. Appreciate the help!
Figured it out. When you go to [Settings] and select [Sounds] under the [General] tab you can verify that your ringer and alerts volume level is above zero, and when moving the slider the device will chime at the newly set level. In addition you will note that all of your specific tones are enabled in the list below. This is what threw me off when checking the device settings. I launched YouTube and other applications and was able to play sound just fine.
What I didn't realize until I spoke to another guy (who knows the product a little better), is that there is another method to mute system sounds. By pressing the circle button twice an icon bar is revealed on the bottom of the screen. If you drag the icons to the right with your finger a speaker icon is revealed. This happened to be muted for some reason...presumably after I performed a system restore recently. Tap it to un-mute and your back in business. Not sure why Apple designed it this way, but it would have been helpful (and saved me a few hours of tinkering) if it had been accessible under the device settings.
I don't think you can play an mp3 file on the device using AudioServicesPlaySystemSound
AudioServicesPlaySystemSound apple document
-(void)playAif:(NSString *)filename {
// NSLog(#"play: %#", filename);
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle]
pathForResource:filename ofType:#"aif"];
if (path) { // test for path, to guard against crashes
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound; // 1
AudioSessionSetProperty (
kAudioSessionProperty_AudioCategory, // 2
sizeof (sessionCategory), // 3
&sessionCategory // 4
);
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);
AudioServicesPlaySystemSound (soundID);
}
}
I've been trying to work out this problem for a good 48 hours now and haven't come up with anything. I have 2 AVPlayer objects playing different http live streams. Obviously, I don't want them both playing audio at the same time so I need a way to mute one of the videos.
Apple suggests this for muting an audio track playing in AVPlayer...
NSMutableArray *allAudioParams = [NSMutableArray array];
for (AVPlayerItemTrack *track in [_playerItem tracks]) {
if ([track.assetTrack.mediaType isEqualToString:AVMediaTypeAudio]) {
AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
[audioInputParams setVolume:0.0 atTime:CMTimeMakeWithSeconds(0,1)];
[audioInputParams setTrackID:[track.assetTrack trackID]];
[allAudioParams addObject:audioInputParams];
// Added to what Apple Suggested
[track setEnabled:NO];
}
}
AVMutableAudioMix *audioZeroMix = [AVMutableAudioMix audioMix];
[audioZeroMix setInputParameters:allAudioParams];
[_playerItem setAudioMix:audioZeroMix];
When this didn't work (after many iterations), I found the enabled property of AVPlayerItemTrack and tried setting that to NO. Also nothing. This doesn't even register as doing anything because when I try an NSLog(#"%x",track.enabled), it still shows up as 1.
I'm at a loss and I can't think of another piece of documentation I can read and re-read to get a good answer. If anyone out there can help, that would be fantastic.
*Update: I got a hold of Apple and according to the AVFoundation team, it is impossible to mute or disable a track of an HLS video. I, personally, feel like this is a bug so I submitted a bug report (You should do the same to tell Apple that this is a problem). You can also
try and submit a feature enhancement request via their feedback page.
New iOS 7 answer: AVPlayer now has 2 new properties 'volume' and 'muted'. Use those!
And here is the original answer for life before iOS 7:
I've been dealing with the same thing. We created muted streams and streams with audio. To mute or unmute you call [player replaceCurrentItemWithPlayerItem:muteStream].
I also submitted a bug report. It looks like AVPlayer has this functionality on MacOS 10.7, but it hasn't made it to iOS yet.
AVAudioMix is documented not to work on URL assets here
Of course I tried it anyway, and like you I found it really doesn't work.
The best solution for this would be to actually embed the stream url feed with two audio tracks! One would be with the normal audio and the other audio track would be the muted audio.
It makes more sense to do it this way rather then the way ComPuff suggested as his way your actually creating two separate URL streams - which is not required.
Here is the code that you could use to switch the audio tracks:
float volume = 0.0f;
AVPlayerItem *currentItem = self.player.currentItem;
NSArray *audioTracks = self.player.currentItem.tracks;
DLog(#"%#",currentItem.tracks);
NSMutableArray *allAudioParams = [NSMutableArray array];
for (AVPlayerItemTrack *track in audioTracks)
{
if ([track.assetTrack.mediaType isEqual:AVMediaTypeAudio])
{
AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
[audioInputParams setVolume:volume atTime:kCMTimeZero];
[audioInputParams setTrackID:[track.assetTrack trackID]];
[allAudioParams addObject:audioInputParams];
}
}
if ([allAudioParams count] > 0) {
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
[audioMix setInputParameters:allAudioParams];
[currentItem setAudioMix:audioMix];
}
The only problem is that my stream url is only display two tracks (one for video and one for audio) when it should actually be three tracks (2 audio tracks). I cant work out if this is a problem with the stream url or my code! Can anyone spot any mistakes in the code?
I am trying to set custom local notification sound like this:
UILocalNotification *notification = [UILocalNotification new];
notification.timeZone = [NSTimeZone systemTimeZone];
notification.fireDate = date;
notification.alertAction = #"123";
notification.alertBody = #"123";
//!!!
notification.soundName = #"Glass.aiff";
alarmID=[NSString stringWithFormat:#"%i", arrayAlarms.count];
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:alarmID forKey:#"id"];
notification.userInfo = infoDict;
notification.repeatInterval=NSWeekCalendarUnit;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
But I hear only default sound. I am testing app on ios5. Great thanks for help in advance and sorry for my english.
Custom Notification sounds are restricted to less than 30 seconds. If your sound is longer than this iOS will play the default sound instead. Could this be your problem?
For more info see here. https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html
"Custom sounds must be under 30 seconds when played. If a custom sound is over that limit, the default system sound is played instead."
Check your syntax , its wrong. check with this,
notification.soundName = "Glass.aiff";
One can still use UILocalNotificationDefaultSoundName for default local notification sound.
notification.soundName = #"Glass.aiff";
That should work. Make sure the sound(Glass.aiff) is actually in your app’s bundle, and is under 30 seconds.We can't set a custom sound that not present in our app's bundle ie from Document folder etc.
First off, I'm fairly new with objective C. I want to play a sound and vibrate under a certain condition. My iPhone 4 is not on mute, I've checked case sensitivity and used both AVAudioPlay and SystemSound to try and play the file but even the vibrate will not work. AudioToobox and AVfoundation are imported in .h. The audio plays with both methods on the iOS simulator.
Heres the code using SystemSound:
if (al == 1){
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef =CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"Alarm", CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);}
And with AVAudioPlayer:
if (al == 1) {NSString *path = [[NSBundle mainBundle] pathForResource:#"alarmtwo" ofType:#"wav"];
AVAudioPlayer *theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.numberOfLoops = 0;
theAudio.volume = 1.5;
[theAudio prepareToPlay];
[theAudio play];}
By the way, the variable al sets to 0 after it plays. Is my coding wrong to have the sound and vibrate work on the device itself? Is there a specific type of .wav file that needs to be played? Any help would be appreciated.
I was running into this same issue. There is actually a second volume setting specially for alerts that at least in my case was set to mute, even though my regular volume was up. Take a look under the sounds menu in the Settings app on the device and turn that up.
You probably don't want to use the alerts for an actual released app though if it is important that the sound actually play, since it will require users to make sure this separate audio setting is up.