How do I play the shutter sound from iPhone when I click a button?
You can use AudioToolbox and pure magical number 1108 like this:
Swift:
import AudioToolbox
AudioServicesPlaySystemSound(1108)
Objective-C:
#import <AudioToolbox/AudioToolbox.h>
AudioServicesPlaySystemSound(1108);
Here is full list of these pure magical ids.
1) Search online for a camera shutter wave file. You can trim this one if it is a bit long using a .wav editor
http://www.freesound.org/people/Nathan_Lomeli/sounds/79190/
2) Name it shutter.wav and put it into your development directory along with your other resources.
3) Define the sound in your view's .h file
#interface myViewController : UIViewController {
SystemSoundID SoundID;
}
4) Load the file in your View's "viewDidLoad" event:
//load a sound wav file to use for the shutter
NSURL *buttonURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"shutter" ofType:#"wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)buttonURL, &SoundID);
5) In your button_click event:
//play then shutter.wav sound
AudioServicesPlaySystemSound(SoundID);
some sounds to pick to those location : /System/Library/Components/CoreAudio.component/Contents/SharedSupport/SystemSounds
/System/Library/Sounds
You don't specify a programming language, but let's assume ObjC for now and not Monotouch or any other 3rd party framework.
AVAudioPlayer from the AV framework is your friend.
Please see the documentation here at Apple
Or do a search on AVAudioPlayer here on SO and you will find dozens of examples.
Still, you will have to grab the shutter sound file from somewhere but you can take any public available shutter WAV you find on Google.
If you really want to use the camera, the shutter sound will be played automatically when a picture is taken but I doubt that is what you want.
Related
I need to play midi file or midi tone in iPhone.
I have tested MidiMonitor. I think that I need to create a destination point on the iPhone to receive midi, but I don't know how do it.
Can you help me? Example source code would be useful.
Like #skinnyTOD noted, from iOS 5.0 on it is possible to use MediaPlayer.
First link the AVFoundation, and AudioToolbox frameworks to your project, then use this code:
#import <AVFoundation/AVFoundation.h>
NSURL *midiUrl = [[NSBundle mainBundle] URLForResource:#"even voor mij" withExtension:#"mid"];
MusicPlayer player = NULL;
NewMusicPlayer(&player);
MusicSequence sequence = NULL;
NewMusicSequence(&sequence);
MusicSequenceFileLoad(sequence, (__bridge CFURLRef)midiUrl, NULL, NULL);
MusicPlayerSetSequence(player, sequence);
MusicPlayerStart(player);
This sets up the player with your midi file from bundle, and start playing.
Note that you will need to call DisposeMusicSequence and DisposeMusicPlayer when cleaning up the player.
If you are still trying to sort this, iOS 5 includes the MusicPlayer API - it can load, play and create midi files. You'll need to also read up on the new AUSampler AudioUnit.
I'm using the following to play an m4a file:
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: fileName];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);
It works fine on the simulator but I hear nothing on the device. Sounds files I'm using all stay in the bundle. Here is what filePath looks like from the device:
file://localhost/var/mobile/Applications/418945F3-3711-4B4D-BC65-0D78993C77FB/African%20Adventure.app/Switch%201.m4a
Is there an issue with the file path or any thing different I need to do for the device?
Just as a sidenote - I was having the exact same problem and spent probably close to an hour on converting files to the correct format, etc.. Yet the problem was the "mute" switch on the iPad. So even though the volume was up, and I could hear other sounds on the iPad, because the mute switch was turned on, it wasn't playing system sounds.
To add to the confusion, this app uses text-to-speech and the volume coming from the dictation was perfectly fine, it was only the sounds coming from AudioServicesPlaySystemSound() that weren't being played.
I had trouble with this too. Finally I realised it was because AudioServices can only play audio with the following constratints.
Sound files that you play using this
function must be:
- No longer than 30 seconds in duration
- In linear PCM or IMA4 (IMA/ADPCM) format
- Packaged in a .caf, .aif, or .wav file
From Apple docs: http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/SystemSoundServicesReference/Reference/reference.html
You might want to use the AVAudioPlayer instead of AudioServices.
The following code will take an audio file (.m4a) and play the audio file 1 time. Don't forget to release "audioPlayer" when you're done with it.
NSString *urlAddress = [[NSBundle mainBundle] pathForResource:#"filename" ofType:#"m4a"];
NSURL *url = [NSURL fileURLWithPath:urlAddress];
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
if (audioPlayer == nil)
{
NSLog([error description]);
}
else
{
[audioPlayer play];
}
Hope this example helps you with playing audio on the actual device. It might also be a good idea to increase the device audio when the file is playing.
Note: You will need to add the AVFoundation framework to your project if you have not already done so. As well as import the header file.
#import <AVFoundation/AVFoundation.h>
Update:
From Apple's Core Audio Overview Document
Audio Session Services
Audio Session Services lets you manage audio sessions in your application—coordinating the audio behavior in your application with background applications on an iPhone or iPod touch. Audio Session Services consists of a subset of the functions, data types, and constants declared in the AudioServices.h header file in AudioToolbox.framework.
The AVAudioPlayer Class
The AVAudioPlayer class provides a simple Objective-C interface for playing sounds. If your application does not require stereo positioning or precise synchronization, and if you are not playing audio captured from a network stream, Apple recommends that you use this class for playback. This class is declared in the AVAudioPlayer.h header file in AVFoundation.framework.
Start by error-checking your returns. Is filePath nil? Do either of the AudioServices functions return an error? The most likely cause is case-sensitivity. The iPhone filesystem is case sensitive while the Mac is not. But the first step in debugging is to look at the errors the system is providing.
The simulator uses regular QuickTime for playback, so it's easy to have media assets which work in the sim, but fail on the device due to missing / unsupported codecs. The test is if you can play the file at all on the device, eg through Safari or the iPod app.
I've made a simple app, where I have a list of songs. The user taps a list entry and the song begins playing.
I've lifted the SoundEffect class from Apple's sample projects (e.g. Metronome, BubbleLevel). It seems to work fine with the following code:
// declare in the .h file
SoundEffect *audio;
// setup - when controller loads
audio = [SoundEffect alloc];
// play when user taps entry
NSBundle *mainBundle = [NSBundle mainBundle];
[audio initWithContentsOfFile:[mainBundle pathForResource:#"entry1" ofType:#"mp3"]];
[audio play];
However, if the 'audio' object is already playing, I'd like to stop it before it starts playing the sound again. SoundEffect class does not have a stop method or I am simply missing something.
How do i stop the audio before playing it again?
Why don’t you simply use AVAudioPlayer?
The SoundEffect class is a wrapper around the C-based System Sounds API (see the .m file from the Bubble Level project), which is a simple "fire and forget" style API that doesn't provide a "stop" function. More info in the System Sounds Services Reference.
I also agree with (and have voted up) zoul's suggestion to use AVAudioPlayer. System Sounds are wholly inappropriate for long, encoded audio files like songs in MP3 files.
Apple lists (http://developer.apple.com/samplecode/AudioQueueTest/listing1.html) as a quick demonstration of playing an audio file.
Is there a way to play an audio file with many less lines of code?
Here's a quick and dirty way to do sounds. It's suitable for playing short sounds with no control over duration, volume or precise timing. With those disclaimers, here we go.
In the view controller that will play the sound, import this framework:
#import <AudioToolbox/AudioToolbox.h>
Then manually add the AudioToolbox framework to your project with: Control-click on Frameworks Group --> Add... --> Existing Frameworks... --> AudioToolbox.framework
Next, add 'someSound.caf' to your project Resources folder, obviously use your actual filename.
Inside the method that plays your sound, add:
SystemSoundID theSound;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"someSound" ofType:#"caf"]], &theSound);
AudioServicesPlaySystemSound(theSound);
I use this method for prototyping, not for production code, because of it's many limitations.
Is there a way to programmatically invoke the keypad "click" sound? My app has a custom keypad (built out of UIButtons) and I'd like to provide some audio feedback when the user taps on the keys. I tried creating my own sounds in Garageband, but wasn't happy with any of my creations. If there isn't a standard way to invoke the key click, can anyone point me to a library of sounds that might have such a gem?
There is a really fast solution to play the default keyboard sound:
Add AudioToolbox.framework
Add the following line wherever you want the sound to play:
AudioServicesPlaySystemSound(0x450);
As of iOS 4.2, adopt the UIInputViewAudioFeedback protocol on a custom subclass of UIView. Make this view your "inputView" and then call "playInputClick" at the appropriate time.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIInputViewAudioFeedback_ProtocolReference/Reference/Reference.html
Just to save some people time. Put this in your custom view:
- (BOOL) enableInputClicksWhenVisible {
return YES;
}
To make the click do this:
[[UIDevice currentDevice] playInputClick];
No need to copy the file into your own app - you should be able to get it directly from the UIKit framework:
CFURLRef soundFileURLRef = CFBundleCopyResourceURL(
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.UIKit")),
CFSTR ("Tock"),CFSTR ("aiff"),NULL);
This is what I made out of it aSquared's comment:
NSString *path = [[NSBundle bundleWithIdentifier:#"com.apple.UIKit"] pathForResource:#"Tock" ofType:#"aiff"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &soundID);
AudioServicesPlaySystemSound(soundID);
AudioServicesDisposeSystemSoundID(soundID);
The simplest way I've found is to extract Tock.aiff (the keyboard sound) from the iPhone Simulator and package it with your app, then play it using AudioServicesPlaySystemSound() at the appropriate time. On my machine, simply typing Tock.aiff into Spotlight turns up the file, but if you have to go looking for it, it's in the simulator version of UIKit.framework.
Using 0x450 as the SystemSoundID works for me (and at the correct volume - just playing the built-in Tock.aiff was too loud). No idea how portable that is - this is on an iPod Touch 3rd gen.
Still doesn't respect the preference for tick on/off.
Here's what I did:
Locate 'Tock.aiff' in: /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/System/Library/Frameworks/UIKit.framework
Drag it into your Resources folder in xCode, ticking 'Copy items into destination group's folder'
Import AVFoundation.framework into the Frameworks folder in xCode
Import AVFoundation at the top of your class:
#import <AVFoundation/AVAudioPlayer.h>
Use the following function:
- (void)PlayClick {
NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"Tock"
ofType:#"aiff"]];
AVAudioPlayer *click = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
[click setVolume:0.15f];
[click play];
}
That's it!
From what I can tell, the click sound isn't available to apps. I haven't seen anything in audio session services that is relevant. AudioServicesPlaySystemSound() looks promising, but there doesn't appear to be any system sound ID for the click sound (a closer look at the headers may turn up something). You could always loop over a call to AudioServicesPlaySystemSound(i) and see if anything plays. The iPhone software restore images probably have the sound, but it's probably not licensed for general use. Jailbreaking an iPhone to get at the tasty click sound doesn't need to be mentioned.
For (creative commons) sounds, check out the Freesound Project.
For the future, perhaps request that Apple expose system sounds other than the alert sound for use with AudioServicesPlaySystemSound().
Maybe a bit late ...
But in MrMage last post, if you do AudioServicesDisposeSystemSoundID(soundID); straight after AudioServicesPlaySystemSound(soundID);
then you won't hear a thing as you're discarding the system sound right after creating it.
You have to let it finish playing first.. Only call AudioServicesDisposeSystemSoundID to cancel the sound before it finishes
You do not have to dispose of the sound object right away.
Keep a pointer to that sound object in a property, and dispose of it only when you are about to play another sound before re-creating it.
And of course finally dispose of the SystemSoundID object in dealloc.