Codea 1.5.2 Beta

I’m unsure on the camera stream, basic types will probably come first.

Note that you don’t have to use the GCD singleton code — I simply used it in the GameCenter test because I needed to attach the addon as a delegate to the GKGameCenterViewController from inside the exported Lua function, this was the cleanest way I could think to have access to the specific instance of the addon. This made the code more complex than I liked.

The singleton pattern is helpful if you need to manipulate/access the singular instance of your addon in exported Lua functions.

Ok, works fine anyhow. Was thinking of removing it, since I haven’t read about GCD yet, but then I got use for it in the facebook share function, since I call presentViewController and need the CodeaViewController.

I tried using startRecording and stopRecording. It doesn’t seem to work, or no video is saved anyway.

I got AVAudioPlayer working using the new add on functionality. The add on code is available here: https://gist.github.com/reefwing/5377746 and there is a tutorial on it here: http://codeatuts.blogspot.com.au/2013/04/tutorial-28-codea-v152-objective-c-add.html

I like the new API. My biggest issue was trying to call an objective c method from within a c function. What I have done feels like a bit of a hack, so if there is a more elegant way then I would love to learn it.

I didn’t use @Simeon’s singleton pattern for a couple of reasons:

  1. Just to see if I could; and
  2. The extra singleton code obfuscates the learning process a bit and could be intimidating for 1st time Xcoders. I wanted to show how simple it is to add functionality using this new protocol.

As always - comments welcome.

Bug: The back camera seems to be mirrored horizontally. Or at least in the camera sample.

Nice audio example!

Thanks @tnlogy - I just followed yours and @Simeon’s lead.

I’ve updated the audio add on so that you can control the volume of the player from your Lua code and that works great. So getting values from Lua to Objective C is all good but I’m having problems going the other way.

I’m trying to provide a dB meter as part of this audio add on. To that end I need to read an integer from my add on method within the draw loop. I’m using the Cider dial control (which looks great) like this:

function draw()
    dial.val = peakPowerForPlayer() or 0
end

The app crashes (the old EXC_BAD_ACCESS) as soon as the mp3 starts playing. Any ideas what I am doing wrong? I think the issue is that I am not returning a valid integer in peakPowerForPlayer(). The associated Objective C method getPower seems to work ok.

The relevant code is shown below.

- (int)getPower
{
    if ([self.player isPlaying])
    {
        //  Refresh the average and peak power values for all channels of our audio player.
        
        [self.player updateMeters];
        
        //  A floating-point representation, in decibels, of a given audio 
        //  channel’s current peak power.
        //  A return value of 0 dB indicates full scale, or maximum power; 
        //  a return value of -160 dB indicates
        //  minimum power (that is, near silence).
        //
        //  If the signal provided to the audio player exceeds ±full scale, 
        //  then the return value may exceed 0
        //  (that is, it may enter the positive range). For simplicity we will 
        //  only return the power from channel 0.
        
        float power = [self.player peakPowerForChannel: 0];
        
        //  Our dial is expecting a value between 0 and 100.
        
        if (power >= 0)
            return 100;
        else
        {
            power += 160.0f;    //  power is now a +ve float between 0 and 160
            power = (power / 160.0f) * 100.0f;      //  change to a percentage
            return (int)power;
        }
    }
    else
        return 0;
}

//  C Functions

static int peakPowerForPlayer(struct lua_State *state)
{
    return [audioAddOnInstance getPower];
}

```

@Reefwing unfortunately interfacing with Lua is a bit complicated.

Your function:

static int peakPowerForPlayer(struct lua_State *state)
{
    return [audioAddOnInstance getPower];
}

```


Should not be returning a value directly — the returned value from *all* exported Lua functions is how many values that function should return in Lua.

For example, if you return 0 from that function, you are telling Lua that peakPowerForPlayer returns 0 values. If you return 2, you are telling Lua to expect 2 values on the stack when the function returns.

To actually return values, you need to push them onto the Lua stack and then return the number of values you pushed on. So this should work:

static int peakPowerForPlayer(struct lua_State *state)
{
    //Push the integer on the stack
    lua_pushinteger(state, [audioAddOnInstance getPower]);

    return 1; //Our function returns 1 value
}

```

@Simeon - that would explain it. Thanks for the info, it now works. I will post the new add on code tonight.

Here is a link to the updated audio framework: https://gist.github.com/reefwing/5377746

The following functions are available in Codea once the audio add on is registered:

playMusic()
stopMusic()

getVolume()                -- returns an integer between 0 and 100
setVolume(setting)      -- expects setting to be between 0 and 100

peakPowerForChannel(channel)
averagePowerForChannel(channel)

I used the Cider dial and donut for the left and right dB level meters, and the Cider slider for the volume control. So you will need to include these as a dependency. Thanks to @Mark for his work on these, they look great. You may have to tweak the position of the controls, for some reason they moved when I exported them from Codea into Xcode.

Feel free to expand/modify or otherwise use the code. The meters would look better with a slow animation to zero when the mp3 is stopped. Passing in an mp3 name to play is another obvious extension.

@Simeon - would it be possible to expose:

- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation

in the CodeaViewController header file? That would simplify handling rotation in add ons.

You could subclass it and override those methods in your subclass, then instantiate that inside the AppDelegate instead.

The CodeaViewController versions of those methods are complicated because they allow the Lua call supportedOrientations to function.