GithubHelp home page GithubHelp logo

zoul / finch Goto Github PK

View Code? Open in Web Editor NEW
436.0 32.0 345.0 4.63 MB

Simple, low-latency OpenAL sound engine for Apple iOS.

Home Page: http://github.com/zoul/Finch/

License: MIT License

Objective-C 91.86% Ruby 8.14%

finch's Introduction

About

Finch is a simple OpenAL-based sound effect player for iOS. The reasons for writing Finch instead of sticking with Apple’s AVAudioPlayer are described in my question on Stack Overflow. The goals are simple: (1) Play sound effects without much fuss, and (2) do not lag in the play method as AVAudioPlayer does. Finch is not meant to play background music. If you want to play background music, you can go with AVAudioPlayer. Finch will play the sound effects over the background music just fine.

Installing

Finch is a static library. Your best bet is to use the “workspace” Xcode 4 feature, adding the Finch project into your project’s workspace and linking the appropriate target against libFinch. The only remaining thing is taking care of headers. This is a bit clumsy (see another SO question), but in essence you can put Finch into a folder inside your project (say Support) and set the user header search path to this folder and below (Support/**).

If you are unsure about the instructions above, please see the Xcode 4 static libraries tutorial by Jonah Williams.

Using

After you link against the library and import the headers you may start using the code:

#import "FISoundEngine.h"

NSError *error = nil;
FISoundEngine *engine = [FISoundEngine sharedEngine];
FISound *sound = [engine soundNamed:@"finch.wav" maxPolyphony:4 error:&error];
if (!sound) {
    NSLog(@"Failed to load sound: %@", error);
} else {
    [sound play];
}

Sound loaded without the maxPolyphony argument will only play with one “voice” at a time. If you call play before such sound is finished, it will play again from the start:

-----------------> time
ra
  ra
    rapid fire!

If you wish to overlay multiple instances of the sound, set the maxPolyphony argument to maximum number of sounds that you need to layer:

-----------------> time
rapid fire!
  rapid fire!
    rapid fire!

And please note that Finch does not yet support compressed audio. You should be safe with 8-bit or 16-bit mono or stereo little-endian WAV files sampled at 44.1 kHz. There is a demo target inside the project, take a look at it to see more.

Audio Interruption Handling

Your app’s audio session may be interrupted at any moment, be it with an incoming call, the iPod playback being started or whatever else. In this case you are reponsible for correctly suspending your audio session and resuming it later when the interruption ends. This is a bit hard, since the sound system is very particular about your suspend and resume code.

Finch currently supports suspend and resume with the suspended property of the FISoundEngine class. When you receive an interruption notification or callback from the system, you can set this property to YES and later flip it to NO when the interruption has ended. There’s a slight catch, though – when your app receives a notification about the interruption being ended, your app still may be in background and therefore it can’t resume the sound session right away. You have to wait until the app is active again and only then resume the sound engine. See the application delegate in the demo project about how this can be done. (Also notice that the audio session delegates, callbacks and notifications differ between iOS versions.)

Further info may be found in the documentation for the AVAudioSession class.

Hacking

The FISoundEngine and FISound classes are just a thin layer atop of the plumbing classes that implement the actual OpenAL primitives. See the Xcode project to learn more, it’s fairly easy to do your own things if you need to. Some links you might find useful:

License

The code is offered under the MIT License. Essentially you can do with this software whatever you like, provided that you keep the copyright notice and the license text along.

Authors & Support

Code by Tomáš Znamenáček, [email protected].
The Finch image is © asukawashere.

If you have a question that could possibly be of interest to other people, you can ask it on Stack Overflow and send me a link to your question. It’s better than discussing it in private, because you can get answers from other people and once the question has been answered, other people can benefit from the answer, too.

finch's People

Contributors

capnslipp avatar marlonandrade avatar zoul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

finch's Issues

Add namespace prefixes

First of all, thanks for all the great work!

It would be great if you could add a namespace to the library to avoid namespace collosions!

For instance, the class name "Decoder" is quite likely to already exist in a large project where Finch is imported. "FIDecoder", "FNDecoder", or just about any prefix if your choice would be much better! Just make sure that the prefix letters aren't already in use by any existing iOS library.

Stopping a paused sound doesn't

If you pause a sound that's playing, and then stop it, the library doesn't stop it, which means that if you then try to resume the sound, it will start playing again. The normal behavior ought to be that if you stop a sound, it doesn't start playing when you try to unpause (ie resume) it.

The problem lies in these lines in FISoundSource.m:

- (void) stop { if ([self isPlaying]) { alSourceStop(_handle); } }

The conditional should also check if the sound is currently paused.

There was an error loading a sound: No suitable decoder found

Finch seems great, but I'm trying to load uncompressed wavs and getting this in the console (on simulator and device):

"AudioStreamBasicDescription: 2 ch, 44100 Hz, 'lpcm' (0x00000C2C) 8.24-bit little-endian signed integer, deinterleaved
2010-10-31 13:56:15.560 xxxx[2822:307] There was an error loading a sound: No suitable decoder found for /var/mobile/Applications/.../xxxx.app/solved.wav."

My code:

soundEngine = [[Finch alloc] init];
NSString *pathToSolvedSound = [[NSBundle mainBundle] pathForResource:@"solved.wav" ofType:nil];
solvedSound = [[Sound alloc] initWithFile:pathToSolvedSound];

It's happened with multiple wav files from different sources.

Error when compiling Demo

Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang failed with exit code 1

I tried to compile the Demo for the simulator on my machine and got the above error. I changed the Active SKDSs to 4.0/4.1 and saw the same error. I couldn't see anything else in the project settings which might be causing this.

the clang file is where it should be on my system. XCode 3.2.4 with SDKs 4.0 and 4.1 installed on MacBook Pro.

Better error handling

After the rewrite most of the error handling code got axed, we should at least log the errors found during sound loading.

Has it been tested on iPad?

Hi. I like Finch's simplicity and I'm going to use it in production code. Therefore I'd really like to know whether it has been tested on iPad devices. Does it still mix fine with AVAudioPlayer and the device library music?
Thanks!

Stopping a revolver sound stops the wrong sample

Current code:

- (void) play
{
    [(FISound*) [voices objectAtIndex:current] play];
    current = (current + 1) % [voices count];
}

- (void) stop
{
    [[voices objectAtIndex:current] stop];
}

Now the current index gets bumped when the sample starts playing, so that we can’t use it to stop.

Audio Wont Play

I am probably doing something rather stupid but i just cannot figure it out. I am new to this. Any help would be appreciated.
- (void)viewDidLoad{
[super viewDidLoad];
engine = [[Finch alloc] init];
snare = [[Sound alloc] initWithFile:
[[NSBundle mainBundle] URLForResource:@"snare" withExtension:@"wav"]];
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    if (acceleration.z < -0.7)
        [snare play];
}

Better decoder design

If we want the decoder stuff to be useful for other people, we have to separate the file reading from decoding and we have to decode the audio in chunks if the caller wants to.

Sound length is broken

The sound length property does not work. It’s a trivial fix, I’ll do it as soon as I have a few minutes to spare.

Add CocoaPods support

Would be great if someone could make a Cocoapod for this, os it can be installed via Cocoapods!

Make Finch a singleton class

I would to see Finch be made into a singleton class.

Reason being, a iPhone app may have several view controllers, and someone could try
to create many factories/engines, that is to say, one in each view controller. This is bad.

However, since an iOS app should only be using one device and one context with OpenAL,
there will be conflicts opening and closing the same device.

So, there should only be one FIFactory/FIEngine class for the entire app.

Cached sound system

It would be nice if Finch provided a cached sound system.

You could store a NSMutableDictionary of loaded sound filenames and return
the loaded sound if it exists.

It would be similar to Apple's image caching system for imageNamed.
Cached sound files don't have to be loaded again, reducing lag.

Convert mono samples to stereo

Hello,

I would like to see a method to convert mono samples to stereo, before
they are sent to OpenAL.

This would allow me to store all of my sounds on file as mono (less space), and then I can
convert them to stereo before playing them.

Sound playback delayed on first playback

i have
[FISoundEngine sharedEngine];
in appdelegate

self.btnSound = [engine soundNamed:@"tapMusic.wav" maxPolyphony:4 error:NULL];

when [self.btnSound play] the first time,it stick,then no stuck

Volume Control?

Hey,

Is it possible to control the volume of the sounds?

I'm using Finch for some sound effects in my game, similar to my background music volume slider I'd like to add one for sound effects.

Could you please point me in the correct direction?

Thanks
Luke

Add MP3 decoding

wav and caf are too big; I have about 40 sound effects I want to use. In linear pcm that comes to about 17MB.

Compiling for arm64 architecture

In order to compile for arm64 architecture, you'd need to change following line in FISampleBuffer.m and add casts to int, as the arm64 NSUInteger is a "long" primitive in 64bit architectures. I changed that, and the library seemed to work fine.

alBufferData(_handle, [self OpenALSampleFormat], [data bytes], [data length], sampleRate);

to

alBufferData(_handle, [self OpenALSampleFormat], [data bytes], (int)[data length], (int)sampleRate);

Recording?

Is there a way to record the sounds played via Finch?

FYI: No Sound From Finch w/ OpenEars in iOS 4.3.x

I was having problems getting audio to play on iPhones running iOS 4.3 after OpenEars had initialized its audio session. The strangest part was that everything worked fine on an iPod Touch with 4.3 and an iPhone with iOS 5.

After a ton of searching, a ton of troubleshooting, and lots of banging my head against the wall I found that I could force the ALCcontext's Frequency to 16000 and sound was working again.

I added the following into the engine code:

int attrlist[] = { ALC_FREQUENCY, 16000, ALC_INVALID };
context = alcCreateContext(device, attrlist);

Obviously, not a robust solution, but I wanted to give you a heads up regarding a potential incompatibility. I unfortunately don't have the time to create a proper patch.

Sound cutting off when phone call comes in

Hey,

I've been experiencing an issue where the sound completely cuts off after a phone call has been answered inside the game. The only way to restore sound after is to restart the app completely (remove from multitasking)

Are there any ways to fix this?

Thanks

Issues with the Installation

Hello,

I'm having some trouble here implementing your code.

First, the demo seems to be not working properly here. It actually builds without any errors, but it doesn't launch the simulator and starts the app. Any ideas? Xcode 4.5.2.

Second, I'm having some trouble adding it as a static library on my app. I added it as a workspace and linked the binary with the library (Build Phases -> Link Binary with Libraries -> libFinch.a), but after that I couldn't find a way to work. It seems to be a popular problem, there are several threads around the web asking for help to install you code, but none of them provides any solution, even on StackOverFlow. Maybe a step by step or more information about it would be very appreciated, not only by me, but for several people around the web with the same problem.

Thanks you for all the trouble making this engine and I hope I can make it work here :)

Thomas

Popping when playing multiple sounds

Hey Zoel,
I've been trying to go off of your Finch Code to play multiple sounds at the same time. If the first sound is playing a pop occurs when the second sound begins which I think is a result of the sound not being preloaded to a buffer. I found some other source codes for openal around the web but they negate the ease of Finch.

here is how I create and play the sounds

string1 = [[Sound alloc] initWithFile:[[NSBundle mainBundle] URLForResource:@"Sound1" withExtension:@"wav"]];
string2 = [[Sound alloc] initWithFile:[[NSBundle mainBundle] URLForResource:@"Sound2" withExtension:@"wav"]];
[string1 play];
[string2 play];

also in Sound.m I tried commenting out the stop.

- (void) play
{
    // if (self.playing)
    // [self stop];
    CLEAR_ERROR_FLAG;
    alSourcePlay(source);
    [self checkSuccessOrLog:@"Failed to start sound"];
}

This eliminates the pop from the sounds if the sound is currently playing.

play1 
play2 *pop*
play1 (play1 and play2 still playing) no pop
play2 (play1 and play2 still playing) no pop
play1 (play1 NOT currently playing and play2 still playing) *pop*

I hope that kind of makes sense. The pop occurs when a sound goes from a non playing state to a playing state while the other sound is playing.

Any advice would be appreciated. I'm been on this thing for weeks now.
Thanks,
Nick

Popping?

First of all, Finch is a great plugin, it has greatly simplified the music app I'm building. Thanks!

Secondly, I have a problem with sounds popping when I stop them. I'm essentially using Finch as a sampler of sorts for when users press notes, it plays the sample I've recorded corresponding to that note. But every time I call "Stop" on the sound, I get a small but noticeable popping sound. It happens sometimes when multiple sounds are played at once when the sound begins, but always happens when you release the sound. Any idea why it might be? I'm not necessarily sure if it has much to do with your code, but I've searched and searched for why this might be happening and can't find anything that fixes it anywhere.

Thanks!

Load sounds by name, not full path

Loading sounds by full path is needlesly complex, we should load sounds from the bundle by name just like many of the Apple classes do.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.