[chuck-users] A problem with the code

lucas samaruga samarugalucas at gmail.com
Fri Apr 18 19:39:12 EDT 2008


Hi list

I'm working with ChucK in a musical project,
and I have a problem with the code.
This code generates 3 different error menssages in my machine
(running chuck-alsa on linux), depending on the amount of
components in an array.

1) A common
[chuck](VM): NullPointerException: shred[id=3:grancassa.ck], PC=[13]

2) A segfault, and

3) A king of 1) + 2) problem
[chuck](VM): NullPointerException: shred[id=3:grancassa.ck], PC=[13]
*** glibc detected *** chuck-alsa: double free or corruption (!prev):
0x08391c50 ***
======= Backtrace: =========
/lib/libc.so.6[0xb7c9d4b6]
/lib/libc.so.6(cfree+0x89)[0xb7c9f179]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7eb4a61]
/usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb7eb4abd]
chuck-alsa[0x8055c25]
chuck-alsa[0x80583aa]
chuck-alsa[0x809b692]
chuck-alsa[0x80564f9]
chuck-alsa[0x8057ac8]
chuck-alsa[0x80afd98]
/lib/libc.so.6(__libc_start_main+0xe0)[0xb7c4cfe0]
chuck-alsa(__gxx_personality_v0+0x3a5)[0x804dfb1]
======= Memory map: ========
08048000-081a6000 r-xp 00000000 08:02 1107555    /usr/bin/chuck-alsa
081a6000-081ce000 rw-p 0015d000 08:02 1107555    /usr/bin/chuck-alsa
081ce000-08456000 rw-p 081ce000 00:00 0          [heap]
b63c4000-b63c5000 ---p b63c4000 00:00 0
b63c5000-b6bc5000 rw-p b63c5000 00:00 0
b6bc5000-b6bc6000 ---p b6bc5000 00:00 0
b6bc6000-b73c6000 rw-p b6bc6000 00:00 0
b73c6000-b73c7000 ---p b73c6000 00:00 0
b73c7000-b7bc9000 rw-p b73c7000 00:00 0
b7bc9000-b7bcd000 r-xp 00000000 08:02 509500     /usr/lib/libogg.so.0.5.3
b7bcd000-b7bcf000 rw-p 00003000 08:02 509500     /usr/lib/libogg.so.0.5.3
b7bcf000-b7c1e000 r-xp 00000000 08:02 510590     /usr/lib/libFLAC.so.8.1.0
b7c1e000-b7c20000 rw-p 0004f000 08:02 510590     /usr/lib/libFLAC.so.8.1.0
b7c20000-b7c33000 r-xp 00000000 08:02 455207     /lib/libpthread-2.6.1.so
b7c33000-b7c35000 rw-p 00013000 08:02 455207     /lib/libpthread-2.6.1.so
b7c35000-b7c37000 rw-p b7c35000 00:00 0
b7c37000-b7d64000 r-xp 00000000 08:02 455181     /lib/libc-2.6.1.so
b7d64000-b7d65000 r--p 0012c000 08:02 455181     /lib/libc-2.6.1.so
b7d65000-b7d67000 rw-p 0012d000 08:02 455181     /lib/libc-2.6.1.so
b7d67000-b7d6b000 rw-p b7d67000 00:00 0
b7d6b000-b7d75000 r-xp 00000000 08:02 455263     /lib/libgcc_s.so.1
b7d75000-b7d77000 rw-p 00009000 08:02 455263     /lib/libgcc_s.so.1
b7d77000-b7d9a000 r-xp 00000000 08:02 455189     /lib/libm-2.6.1.so
b7d9a000-b7d9c000 rw-p 00022000 08:02 455189     /lib/libm-2.6.1.so
b7d9c000-b7df2000 r-xp 00000000 08:02 1237590
/usr/lib/libsndfile.so.1.0.17
b7df2000-b7df4000 rw-p 00055000 08:02 1237590
/usr/lib/libsndfile.so.1.0.17
b7df4000-b7df8000 rw-p b7df4000 00:00 0
b7df8000-b7dfa000 r-xp 00000000 08:02 455187     /lib/libdl-2.6.1.so
b7dfa000-b7dfc000 rw-p 00001000 08:02 455187     /lib/libdl-2.6.1.so
b7dfc000-b7edf000 r-xp 00000000 08:02 510606     /usr/lib/libstdc++.so.6.0.9
b7edf000-b7ee2000 r--p 000e2000 08:02 510606     /usr/lib/libstdc++.so.6.0.9
b7ee2000-b7ee4000 rw-p 000e5000 08:02 510606     /usr/lib/libstdc++.so.6.0.9
b7ee4000-b7eea000 rw-p b7ee4000 00:00 0
b7eea000-b7fa1000 r-xp 00000000 08:02 509387     /usr/lib/libasound.so.2.0.0
b7fa1000-b7fa2000 r--p 000b6000 08:02 509387     /usr/lib/libasound.so.2.0.0
b7fa2000-b7fa6000 rw-p 000b7000 08:02 509387     /usr/lib/libasound.so.2.0.0
b7fa6000-b7fa7000 rw-p b7fa6000 00:00 0
b7fcc000-b7fe6000 r-xp 00000000 08:02 455174     /lib/ld-2.6.1.so
b7fe6000-b7fe8000 rw-p 0001a000 08:02 455174     /lib/ld-2.6.1.so
bfcf2000-bfd07000 rw-p bfcf2000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
Abortado


I think there is not a NullPointerException in the logic of the
chuck code, maybe I'm wrong, but the error menssages 2) and 3) are not
only chuck-code-logic-problems. I can't understand the problem and find
a workaround! If anyone can confirm that the error was due to a bug, or a
mistake in my code,
I will be grateful. Here is the simplificated code...


//**************
// grancassa.ck
//**************

// To Test: $ chuck CADSR.ck percaditiva.ck grancassa.ck

public class GranCassa extends PercAditiva
{
    int afinacion;
    0 => int GRAVE;
    1 => int MEDIO;
    2 => int AGUDO;

    float bfreq;

    constructor();
    fun void constructor() {
//***********************************************************************
// setNComponentes < 5
//   [chuck](VM): NullPointerException: shred[id=3:grancassa.ck], PC=[13]
// setNComponentes = 5
//   segfault
// setNComponentes > 5
//   [chuck](VM): NullPointerException: shred[id=3:grancassa.ck], PC=[13]
//   *** glibc detected *** chuck-alsa: double free or corruption (!prev):
0x083ae308 ***
//************************************************************************
        setNComponentes( 5 );
        setResonancia( 10::second, 4.0 );

        setAfinacion( GRAVE );
        setGanancias( 0 );
    }

    fun float tocar( float n ) {
        setTAtaque( 2::second, 0 );

        n => g.gain;
        noteOn();
    }

    fun float apagar( float n ) {
        if( n > 0.5 ) {
            setTApagado( 0.25::second, -2 );
        }
        else {
            setTApagado( 0.5::second, 2 );
        }

        noteOff();
    }

    fun void setAfinacion( int a ) {
        a => afinacion;
        setFrecuencias();
    }

    fun void setFrecuencias() {
        if( afinacion == GRAVE )
            40.0 => bfreq;
        else if( afinacion == MEDIO )
            80.0 => bfreq;
        else // afinacion == AGUADO
            120.0 => bfreq;

        for( int i; i < ncomp; i++ ) {
            bfreq + bfreq * 0.5 * i +
            ( Std.rand2f( -2.5, 2.5 ) ) => s[i].freq;
        }
    }

    fun void setGanancias( int material ) {
        for( int i; i < ncomp; i++ ) {
            1.0 / (i + 1.0) => gain[i].gain;
        }
    }
}

// Test

GranCassa gc;
<<< "np" >>>;

gc.connectTo( dac );

while( true ) {
    gc.tocar( 0.5 );
    5::second => now;
    gc.apagar( 0.7 );
    2::second => now;
}
// End of grancassa.ck



//****************
// percaditiva.ck
//****************

// Super class for GranCassa

public class PercAditiva
{
    12 => int MAX_COMP;
    int ncomp;
    SinOsc @ s[MAX_COMP];
    CADSR @ env[MAX_COMP];
    Gain @ gain[MAX_COMP];
    Gain g;

    fun void connectTo( UGen ug ) {
        g => ug;
    }

    fun float setGain( float g_ ) {
        g_ => g.gain;
    }

    fun float getGain() {
        return g.gain();
    }

    fun void setNComponentes( int n ) {
        if( n <= MAX_COMP && n >= 1 ) {
            n => ncomp;
        }
        else {
            <<< "(PercAditiva): Cantidad de componenetes no soportada" >>>;
            <<< "(PercAditiva): ncomp = 6" >>>;
            6 => ncomp;
        }

        for( int i; i < ncomp; i++ ) {
            SinOsc saux @=> s[i];
            CADSR caux @=> env[i];
            Gain gaux @=> gain[i];

            env[i].connectFrom( s[i] );
            env[i].connectTo( gain[i] );
            //s[i] => env[i].g => gain[i];
            gain[i] => g;
        }
    }

    fun void noteOn() {
        for( int i; i < ncomp; i++ ) {
            env[i].keyOn();
        }
    }

    fun void noteOff() {
        for( int i; i < ncomp; i++ ) {
            env[i].keyOff();
        }
    }

    fun void setTAtaque( dur dt, float factor ) {
        for( int i; i < ncomp; i++ ) {
            env[i].setAttack( dt, factor );
        }
    }

    fun void setTApagado( dur dt, float factor ) {
        for( int i; i < ncomp; i++ ) {
            env[i].setRelease( dt, factor );
        }
    }

    fun void setResonancia( dur dt, float factor ) {
        for( int i; i < ncomp; i++ ) {
//*********************************************************
// Commenting the next line, no problem arise (¿?¿?¿?¿?)
//*********************************************************
            env[i].setDecay( dt, float factor );
            env[i].setSustain( 0.0 );
        }
    }
}
// End of percaditiva.ck


//**********
// CADSR.ck
//**********

// CADSR = CurveTable + (stk)ADSR

public class CADSR
{
    CurveTable attack;
    CurveTable decay;
    CurveTable release;
    Gain g;

    dur atime;
    dur dtime;
    dur rtime;

    float acurve;
    float dcurve;
    float rcurve;

    float slevel;
    float clevel; // current level

    float rate;
    float step;

    int state;
    0 => int ATTACK;
    1 => int DECAY;
    2 => int SUSTAIN;
    3 => int RELEASE;
    4 => int DONE;

    constructor();

    fun void constructor() {
        setAttack( 0.5::second, 0.0 );
        setDecay( 0.5::second, 0.0 );
        setSustain( 0.5 );
        setRelease( 0.5::second, 0.0 );

        0.0 => g.gain;
    }

    fun void connectTo( UGen ug ) {
        g => ug;
    }

    fun void connectFrom( UGen ug ) {
        ug => g;
    }

    fun void setAttack( dur t, float curve ) {
        t => atime;
        curve => acurve;
    }

    fun void setDecay( dur t, float curve ) {
        t => dtime;
        curve => dcurve;
    }

    fun void setSustain( float level ) {
        level => slevel;
    }

    fun void setRelease( dur t, float curve ) {
        t => rtime;
        curve => rcurve;
    }

    fun void keyOn() {
        // Si se ataca continua sin apagar, se mantienen los shreds
        // VERIFICAR
        spork ~ computeSamples();
        me.yield(); // para darle oportunidad que corra el shred (?)
    }

    fun void keyOff() {
        if( state == DONE | state == RELEASE ) return;
        RELEASE => state;
    }

    fun void computeSamples() {
        if( state == ATTACK ) {
            // Las CurveTable se inicializan acá porque si no, hay
            // problemas con la inicialización y los índices.
            [ 0.0, 0.0, acurve, 1.0, 1.0 ] => attack.coefs;
            0.0 => clevel;
            0.0 => step;
            1.0 / ( atime / samp ) => rate;

            while( state == ATTACK ) {
                attack.lookup( step ) => g.gain => clevel;
                rate +=> step;

                // La comparación debe ir antes de que se realize el
                // cómputo (pase el tiempo) por la concurrencia
                // de state con respecto a RELEASE. !!!
                if( step >= 1.0 ) DECAY => state;
                1::samp => now;
            }
        }
        if( state == DECAY ) {
            [ 0.0, clevel, dcurve, 1.0, slevel ] => decay.coefs;
            0.0 => step;
            1.0 / ( dtime / samp ) => rate;

            while( state == DECAY ) {
                decay.lookup( step ) => g.gain => clevel;
                rate +=> step;

                if( step >= 1.0 ) SUSTAIN => state;
                1::samp => now;
            }
        }
        // Este no if está demás por el paso del tiempo en el shred
        if( state == SUSTAIN ) {
            while( state == SUSTAIN ) {
                // clevel ~= slevel
                clevel => g.gain;
                1::samp => now;
            }
        }
        if( state == RELEASE ) {
            [ 0.0, clevel, rcurve, 1.0, 0.0 ] => release.coefs;
            0.0 => step;
            1.0 / ( rtime / samp ) => rate;

            while( state == RELEASE ) {
                release.lookup( step ) => g.gain => clevel;
                rate +=> step;

                if( step >= 1.0 ) DONE => state;
                1::samp => now;
            }
        }
        // Este if está demás (?)
        if( state == DONE ) {
            // por si las dudas
            0.0 => g.gain;
            1::samp => now;
        }
    }
}
// End of CADSR.ck


Thanks
Lucas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cs.princeton.edu/pipermail/chuck-users/attachments/20080418/a21c9f04/attachment-0001.htm 


More information about the chuck-users mailing list