Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

beta 1.3



  • Posts: 2,161

    Yeah, I know. Legacy code - from the pre-orientation days. Now that they have the callbacks, I'll fix that.

    I keep hitting "save" as well, and I need to find a font chart to put symbols in the blanks on the keypad.

  • Posts: 384

    Hurrah on your 1.3 submission, TLL!

    I am updating my music player to use the new sound API, and a so very very beta version can be found at:

    -- 0.2.0
    -- Uses new sound() API based on sfxr
    -- Tunes can play independently
    -- made tempo independent for each tune
    -- parses comments

    Still many things to improve. @Simeon, the values for

    sound({StartingPitch = x, SustainTime = y}) 

    did my head in... :) they weren't linear...

  • Posts: 2,161

    I'm also playing with the sound stuff now. I want very precise control over stuff: ideally, I want to produce a continuous sine wave of a specific frequency. Getting the parameters right is proving somewhat tricky when I don't know what that mass of code in the DATA field means.

  • SimeonSimeon Admin Mod
    Posts: 5,700

    @Andrew you can actually write it as a table. The sounds example uses this for the advanced sound.

    The DATA field allows the picker to work without having to insert and update gigantic blocks of code. Unfortunately a soundTable("data string") function didn't make it into 1.3 – I'll have to remember to add it to the issue tracker for one of the next versions. Maybe a sound( DECODE, "data string" ) option instead, that returns the table.

  • BortelsBortels Mod
    Posts: 1,557

    I'd like to chime in here calling for simple mp3 decoding and playing, from the ipod part if necessary, but ideally from sound effects uploaded into a project, much like a spritepack has images (and per-project spritepacks. and a pony).

    But really - I agree with Andrew - one of the frustrating things about sound() for me was no way to say "play a 523.251 Hz tone for 1/2 second".

  • edited January 2012 Posts: 2,161

    I know that I can write it as a table, but I have absolutely no idea what the numbers mean! So I was putting in random numbers to see what happened, and got it so that Codea just leptlayong a continuous high-pitched noise whenever it was open!

    Two bugs: documentation for sound isn't correctly formatted for width. Nd the sound carries on playing when you quit the running program.

  • SimeonSimeon Admin Mod
    Posts: 5,700

    Thanks for the bug report, @Andrew. Can you put them on the issue tracker?

    SFXR is like that – the numbers are "magic" – it's designed to be a game effects generator rather than a generic tone generator. That said, there's no reason we can't consider a separate tone( freq, length, waveform ) API that's not based on SFXR. Consider adding it to the issue tracker if you think it would be useful.

  • Posts: 2,161

    Shall do, when I'm on a computer with the right credentials for logging in to the issue tracker.

  • Posts: 384

    The numbers used as parameters for sfxr are mostly values between 0 and 1. In my beta music player, you will see that I discovered 0.5 = A in the fourth octave, which is 440 hz. Multiplying by 1.295 ish gives the next semitone. 12 of these multiplications gets you to the next octave, 880 hz.

    The values for duration on attack time or sustain are not limited to 1 but they are not in seconds. I think the value can be converted to seconds by taking the square root. @Andrew_Stacey may have given SustainTime a number that lasted some time.

    My initial issue tracker request asked for the ability to specify the frequency and duration directly, because this is the easiest way to generate musical notes. Now that I have figured out how sfxr specifies its frequencies, we should be able to write a small function to convert them. Either more documentation on the sfxr parameters or a separate function would make it easier to work with simple sounds. I travelled the Internet for docs on sfxr and there is not much. There were some comments in a source code port which I can dig up again...

  • SimeonSimeon Admin Mod
    Posts: 5,700

    @Fred - impressive that you managed to figure it out! SFXR is a complicated mess of code. By the way, how is your new ABC player going? Can I get in touch with you over email about getting some sound help on a small project?

  • Posts: 384

    @Simeon, thanks it was a labour of love! Realising you guys didn't write sfxr I figured it would need experimenting with.

    Happy to help with your sound stuff, and a beta version of the new API version of ABCCodeaPlayer is posted above somewhere. Still tweaking it.

  • Posts: 2,161

    Here's a rough signal generator.

    -- Use this function to perform your initial setup function setup()     sa = 0     ta = 0     nu = .4     watch("ElapsedTime")     iparameter("cnu",1,9,10*nu)     iparameter("dhz",-5,5,0)     iparameter("ddhz",-5,5,0)     hz = nu + .001*dhz + .0001*ddhz     hhz = 1000*hz     watch("hhz") end -- This function gets called once every frame function draw()     -- This sets a dark background color      background(40, 40, 50)     -- Do your drawing here     nu = cnu/10     hz = nu + .001*dhz + .0001*ddhz     hhz = 1000*hz     if (ElapsedTime - sa > 2.3) then         sa = ElapsedTime         sound({             Waveform = SOUND_SINEWAVE,             AttackTime = .1,             SustainTime = 1,             SustainPunch = .5,             DecayTime = .1,             StartFrequency = nu,         })     end     if (ElapsedTime - ta > 2.3) then         ta = ElapsedTime         sound({             Waveform = SOUND_SINEWAVE,             AttackTime = .1,             SustainTime = 1,             SustainPunch = .5,             DecayTime = .1,             StartFrequency = hz,         })     end end

    The problems with this are:

    1. Figuring out decent frequencies to play. It would be so much easier if I could specify Hz and be done with it.
    2. To play a continuous tone, it seems that I need to keep replaying it every 2.3 seconds (ish). This leads to a discontinuity that makes it a bit harder to hear the effect that I'm trying to show (beats). Unfortunately, if I make the sustain long then it continues playing after I exit the program and that rapidly becomes annoying (to be clear, it continues playing anyway but with a short sustain then it's not too bad to endure).
    3. The two sounds don't play exactly simultaneously, meaning that when they are of the exact same frequency then whether or not they are in phase or out of phase depends a bit on the frequency. Indeed, there's a slight hiccup when initiating a sound. (Varying the initial values of sa and ta in the above varies the relative restart times of the two notes)

    The second is probably the most important. Fred's figured out a rule-of-thumb for frequencies, it seems, so for the rest I just need to either understand his code or the srfx code (I downloaded it last night as I, also, came up with nothing on the documentation, but it is very opaque) to do that - or hope that Fred takes pity on me and explains it in words of less than one syllable. But having the sound persist after the end of the app is truly annoying. I think I'd really like to be able to define a note via either a duration or by saying "start now" and then later saying "stop" (sometimes real duration and game duration aren't exactly comparable).

  • Posts: 384

    I think I might need your help as a mathematician to explain this one, @Andrew_Stacey!

    Both Hz and sfxr StartFrequency seem to be logarithmic scales.
    440 Hz = 0.5 sfxr and 880 Hz = 0.712880443 sfxr (approx).
    To obtain a 12-tone equally spaced scale in Hz, we multiply each note by the twelfth root of two (1.05946309435929) to obtain the next highest note.
    I achieved the same effect with the sfxr StartFrequency parameter by multiplying by 1.0296. (ish).

    Table 1.
    Note    Hertz   sfxr
    1   440.00  0.5
    2   466.16  0.5148
    3   493.88  0.53003808
    4   523.25  0.545727207
    5   554.37  0.561880733
    6   587.33  0.578512402
    7   622.25  0.595636369
    8   659.26  0.613267206
    9   698.46  0.631419915
    10  739.99  0.650109945
    11  783.99  0.669353199
    12  830.61  0.689166054
    13  880.00  0.709565369

    Could you come up with an equation to convert between Hz and sfxr? It is beyond me... I've done this by ear :)

    I enjoyed listening to the beats between notes from your program. Although I haven't figured this one out exactly, you can roughly convert seconds to sfxr SustainTime by taking the square root of the seconds and multiplying by about 0.666.

    Breaking off any tones still being sustained on exit() would be good.

    I guess for such fine sound comparison, any delay in starting the next sound will put you out of phase. I've been trying to minimise this in my ABC player to get clean chords rather than a 'strum' effect... :)

    sfxr doesn't allow us to vary the parameters during playback, we have to set the duration of the note with SustainTime when we call it. Likewise we can't shift frequencies without starting a new sound. While looping short sounds is possible, it does generate discontinuities. For example, the new version of my piano app: I imagine adding on-the-fly sound modifications would be a significant job, and might not be used as much as other features.

    BTW, has some comments on what all the parameters mean in sfxr. Line 406 onwards is especially illuminating:

    var _lpFilterPos = 0.0; // Confession time
    var _lpFilterOldPos = 0.0;  // I can't quite get a handle on how the filters work
    var _lpFilterDeltaPos = 0.0; // And the variables in the original source had short, meaningless names
    var _lpFilterCutoff = 0.0; // Perhaps someone would be kind enough to enlighten me
    var _lpFilterDeltaCutoff = 0.0; // I keep going back and staring at the code
    var _lpFilterDamping = 0.0; // But nothing comes to mind
    var _hpFilterPos = 0.0; // Oh well, it works
    var _hpFilterCutoff = 0.0; // And I guess that's all that matters
    var _hpFilterDeltaCutoff = 0.0; // Annoying though


  • Posts: 2,161

    Hilarious! (The code comments.)

    I'll take a look and see if inspiration strikes as to rhe formula.

    In the meantime, turns out that youtube is closely connected to google, so I sort of already had a youtube account. Here's a Codea video, made non-interactively via a "playlist" class.

  • BortelsBortels Mod
    Posts: 1,557

    In another thread, @Simeon said:

    1.3 has the Mesh API, which will make shearing very easy.

    So - how? I had thought that if we supported Z, you could just increase the Z dimension and get a shear that way - but it's not there, right? Everything I do maps the texture flat - I can transform and scale and rotate, but no shear. What am I missing?

  • JohnJohn Admin Mod
    Posts: 643

    Shearing is typically a 2D operation, where you shift either side of a geometric primitive in opposite directions - see:

    Are you thinking of perspective distortion? This would require a perspective transform on the z-axis, which is currently unavailable in Codea (unless like Andrew, you do it manually).

  • BortelsBortels Mod
    Posts: 1,557

    The topic was shear, but I was thinking perspective - I can't see how we'd do either with a mesh.

  • JohnJohn Admin Mod
    Posts: 643

    Shear - offset top and bottom vertices by desired shear amount

    Perspective - create a perspective projection matrix then multiply each vertex before setting it on the mesh:
    Not ideal because it's going to be slow compared to using the gpu, but it will work just the same.

  • BortelsBortels Mod
    Posts: 1,557

    Right - but how would we do either in Codea? I don't see either option in the docs, and every time I map a texture... can you share an example chunk of code to do a shear with a mesh?

  • SimeonSimeon Admin Mod
    edited January 2012 Posts: 5,700

    Here's some code for shearing:

    function setup()
        m = mesh()
        m.texture = "Small World:Icon"
        w,h = spriteSize(m.texture)
    function setQuad(m, ll, tl, tr, br)
        local verts = { ll, tl, br, br, tl, tr }
        local tex = { vec2(0,1), vec2(0,0), vec2(1,1),
                      vec2(1,1), vec2(0,0), vec2(1,0) }
        m.vertices = verts
        m.texCoords = tex
    function draw()
        translate(WIDTH/2, HEIGHT/2)
        -- Sheared quad
        setQuad( m, vec2( -w/2 - Shear, -h/2 ), vec2( -w/2 + Shear, h/2 ),
                    vec2(  w/2 + Shear,  h/2 ), vec2(  w/2 - Shear, -h/2 ) )
  • Posts: 2,161

    Here's another video. Looking at it fullscreen (on the computer), I suspect I may need to use bigger fonts in these to make the text clearer.

    @Mark: Was my use of your graph code okay in the pendulum animation? I forgot to ask specifically. Could you release that code under a suitable licence, please?

  • Posts: 1,255

    Everything I've dropped up there is public domain so far as I'm concerned. Consider it under a "do whatever you want" license.

    I'm thrilled to see someone put it to use.

  • BortelsBortels Mod
    Posts: 1,557

    re. the video: yes, bigger fonts. Consider adding a fade transition for the text box. As always - nits, this is a neat video; I like stuff that visualizes math in a way that helps me get an intuitive grasp of the topic.

  • Posts: 2,161

    Mark, thanks. I like it when someone does something that I can grab.

    Bortels, the difficulty with fading the text box is that my current implementation of rounded rectangles involves drawing overlapping components and that doesn't work so well with alphas. I'll redesign it as a mesh, then it'll be easier.

Sign In or Register to comment.