• kroklop92217

    @alexandros thanks, i know bout the github repo, its my primary source of information right now. and thanks for the book recommendation! i tried looking for i pdf online but no luck. do i need to buy an physical copy?

    posted in extra~ read more
  • kroklop92217

    aaand also is there any chance i could get pointed to some other documentation on m_pd.h than the github repository (externals-howto)? i managed to find other resources, but they are just copies of the github (or vice versa i duuno?).

    i could read through the header file and implementation, buuuut i would prefer something more easily digestible.

    thanks! :o)

    posted in extra~ read more
  • kroklop92217

    managed to solve the issue by limiting the interval in which the data are sent (now im sending them only if somethething changed).

    posted in extra~ read more
  • kroklop92217

    So i manageed to sort out the values in the array, it was probably caused by using t_float as type for the array.
    so now when i print value of x->m_state[0][0] in perform function it is 1 asi it should be!
    but for some reason the signal output is still clipping and its laggy and all. same as it was...

    updated code
    simple_matrix~.c

    posted in extra~ read more
  • kroklop92217

    @robertesler thanks again! i got rid of reading the value in perform funuction using matrix_rw and now i just access it via the class object x. but still, the laggy sound remains. one thing is, that instead of being 1, the value from matrix (value that multiplies the incoming signal) is 266830762" that explains a lot, so the laggy sound i caused by clipping of some sort. nooow to figure out where this bug comes from.

    simple_matrix~.c

    //sudo ln /Applications/Pd-0.55-0.app/Contents/Resources/src/m_pd.h m_pd.h
    //snad je to ok udelat takhle no
    
    #include <m_pd.h>
    #include <string.h>
    #include <pthread.h>
    #include <stdarg.h>
    
    
    #define MATRIX_SIZE 7
    #define TRANSM_SIZE 3
    
    
    static t_class *simple_matrix_tilde_class;
    
    typedef struct _simple_matrix_tilde
    {
      t_object x_obj;
    
      t_float some;
    
      int frame;
    
      int val;
      int posx;
      int posy;
    
      char recv[TRANSM_SIZE];
    
      t_float m_state[MATRIX_SIZE][MATRIX_SIZE]; //stav peč desky
      t_float stat;
    
      t_inlet *sym_in_on;
      t_symbol *sgo;
    
      pthread_mutex_t mutex;
    
      t_inlet *sig_one_in, *sig_two_in, *sig_tri_in, *sig_qud_in, *sig_fiv_in, *sig_six_in, *sig_sev_in; 
      t_outlet *sig_one_out, *sig_two_out, *sig_tri_out, *sig_qud_out, *sig_fiv_out, *sig_six_out, *sig_sev_out;
    
    } t_simple_matrix_tilde;
    
    t_float matrix_rw(t_simple_matrix_tilde *x, int op, int c, ...) //x, 0/1, c, x, y, val
    {
      va_list args;
      va_start(args, c);
      
      int xpos;
      int ypos;
      int sval;
      
      int m;
      
      switch(op)
      {
        case 0: //read from timrax
          m = pthread_mutex_lock(&x->mutex);
          xpos = va_arg(args, int);
          ypos = va_arg(args, int);
            
          va_end(args);
          
          pthread_mutex_unlock(&x->mutex);
    
          return x->m_state[xpos][ypos];
      
        case 1: //write to axtirm
          m = pthread_mutex_lock(&x->mutex);
          xpos = va_arg(args, int);
          ypos = va_arg(args, int);
          sval = va_arg(args, int);
            
          va_end(args);
    
          x->m_state[xpos][ypos] = (t_float)sval;
    
          pthread_mutex_unlock(&x->mutex);
            
          return 0;
          
        default:
          //hm
          va_end(args);
          return 0;
      }
    
      if(m)
      {
        //pthread error
        pd_error(x, "pthread mutex lock is behaving :(");
        va_end(args);
        return 0;
      }
    }
    
    void simple_matrix_tilde_oscin(t_simple_matrix_tilde *x, t_symbol *s)
    {
      if(strlen(s->s_name) >= TRANSM_SIZE)
      {
        //sometimes the size is for some reason larger, maybe UDP? crazy guy
        //char recv[TRANSM_SIZE]; //snad to nevybouchne
        memcpy(x->recv, s->s_name, TRANSM_SIZE);
      
        x->val = x->recv[0] - '0';
        x->posx = x->recv[1] - '0';
        x->posy = x->recv[2] - '0';
      
        //post("val %d posx %d posy %d", x->val, x->posx, x->posy);
    
        x->stat = matrix_rw(x, 1, 3, x->posx, x->posy, x->val); //write
      } else 
      {
        //?
      }
    }
    
    t_int *simple_matrix_tilde_perform(t_int *w)
    {
      t_simple_matrix_tilde *x =  (t_simple_matrix_tilde*)(w[1]);
      t_sample *sig_in =          (t_sample *)(w[2]);
      t_sample *sig_out =         (t_sample *)(w[3]);
      int len =                   (int)(w[4]); //lenght of sample
    
      //t_float stat = matrix_rw(x, 0, 2, 0, 0); //read
      for(int u = 0; u < len; u++)
      {
        post("%d", x->m_state[0][0]);
        *sig_out++ = *(sig_in++) * x->m_state[0][0];
      }
    
      return (w+5);
    }
    
    void simple_matrix_tilde_dsp(t_simple_matrix_tilde *x, t_signal **sp)
    {
      dsp_add(simple_matrix_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
    }
    
    void *simple_matrix_tilde_new(t_symbol *s, int argc, t_atom *argv, t_floatarg some)
    {
      t_simple_matrix_tilde *x = (t_simple_matrix_tilde *)pd_new(simple_matrix_tilde_class);
    
      pthread_mutex_init(&x->mutex, NULL);
    
      memset(x->m_state, 0, sizeof(x->m_state));
    
      x->sym_in_on = inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("symbol"), gensym("oscin"));
    
      //wall,
      //wall,
      //x->sig_one_in = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
      //x->sig_two_in = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
      //x->sig_tri_in = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
      //x->sig_qud_in = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
      //x->sig_fiv_in = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
      //x->sig_six_in = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
      //x->sig_sev_in = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
    
      x->sig_one_out = outlet_new(&x->x_obj, &s_signal);
      //x->sig_two_out = outlet_new(&x->x_obj, &s_signal);
      //x->sig_tri_out = outlet_new(&x->x_obj, &s_signal);
      //x->sig_qud_out = outlet_new(&x->x_obj, &s_signal);
      //x->sig_fiv_out = outlet_new(&x->x_obj, &s_signal);
      //x->sig_six_out = outlet_new(&x->x_obj, &s_signal);
      //x->sig_sev_out = outlet_new(&x->x_obj, &s_signal);
    
      return (void *) x;
    }
    
    void simple_matrix_tilde_freedom(t_simple_matrix_tilde *x)
    {
      inlet_free(x->sym_in_on);
    
      inlet_free(x->sig_one_in);
      inlet_free(x->sig_two_in);
      inlet_free(x->sig_tri_in);
      inlet_free(x->sig_qud_in);
      inlet_free(x->sig_fiv_in);
      inlet_free(x->sig_six_in);
      inlet_free(x->sig_sev_in);
    
      outlet_free(x->sig_one_out);
      outlet_free(x->sig_two_out);
      outlet_free(x->sig_tri_out);
      outlet_free(x->sig_qud_out);
      outlet_free(x->sig_fiv_out);
      outlet_free(x->sig_six_out);
      outlet_free(x->sig_sev_out);
    }
    
    void simple_matrix_tilde_setup(void)
    {
      simple_matrix_tilde_class = class_new(
        gensym("simple_matrix~"),
        (t_newmethod)simple_matrix_tilde_new,
        (t_method)simple_matrix_tilde_freedom,
        sizeof(t_simple_matrix_tilde),
        CLASS_DEFAULT,
        0
      );
    
      class_addmethod(simple_matrix_tilde_class, (t_method)simple_matrix_tilde_oscin, gensym("oscin"), A_DEFSYMBOL, 0);
      
      class_addmethod(simple_matrix_tilde_class, (t_method)simple_matrix_tilde_dsp, gensym("dsp"), A_CANT, 0);
      CLASS_MAINSIGNALIN(simple_matrix_tilde_class, t_simple_matrix_tilde, some);
      
    }
    
    

    code responsible for sending data over network (miniosc is needed to compile https://github.com/cnlohr/miniosc/):
    (also run the output as ./a.out <portnumber>)

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    #define MINIOSC_IMPLEMENTATION
    #include "miniosc.h"
    
    int main(int argc, char *argv[])
    {
        //argv[0] must !!
        int port = atoi(argv[1]);
        
        printf("on oprt %d!!\n", port);
    
        miniosc * osc = minioscInit(7000, port, "127.0.0.1", 0);
    
    
        int frame_n = 0;
        int send_test = 1;
    
        int neco[7][7];
        memset(neco, 0, sizeof(neco));
        neco[0][0] = 1;
    
        //printf("%d\n", neco[2][2]);
    
        char path[100];
        char path_one[] = "/matrix/data";
        snprintf(path, sizeof(path), "/matrix/r%d/c%d", 3, 5);
    
        while(1)
        {
            //sleep(1);
            for(int a = 0; a < 7; a++) //7 matrix size
            {
                for(int b = 0; b < 7; b++)
                {
                    //matrix value, pos x, pos y
                    char send_mee[3];
                    send_mee[0] = neco[a][b] + '0'; //jupi
                    send_mee[1] = a + '0';
                    send_mee[2] = b + '0';
    
                    minioscSend(osc, path_one, ",s", send_mee);
                }
            } 
            //send_test++;
            
            //frame_n++;
        }
    
        return 0;
    }
    
    

    testing_tesing.pd patch im testing this stuff on
    Thanks !

    posted in extra~ read more
  • kroklop92217

    @robertesler hi again, i tried implementing simple mutex locking, so in theory only one thread can now read/write to the matrix state array. but surprisingly the issue remains. is my implementation faulty? i thought about adding this access protection to the whole class dataspace, maaaybe it could help, but im not sure really.

    thanks !!

    code added/changed:

    ...
    
    t_float matrix_rw(t_simple_matrix_tilde *x, int op, int c, ...) //x, 0/1, c, x, y, val
    {
      int m = pthread_mutex_lock(&x->mutex);
      
      va_list args;
      va_start(args, c);
    
      int xpos;
      int ypos;
      int sval;
    
      if(!m)
      {
        switch(op)
        {
          case 0: //read from timrax
            xpos = va_arg(args, int);
            ypos = va_arg(args, int);
            va_end(args);
            pthread_mutex_unlock(&x->mutex);
    
            return x->m_state[xpos][ypos];
      
          case 1: //write to axtirm
            xpos = va_arg(args, int);
            ypos = va_arg(args, int);
            sval = va_arg(args, int);
    
            x->m_state[xpos][ypos] = (t_float)sval;
            va_end(args);
            pthread_mutex_unlock(&x->mutex);
    
            return 0;
          
          default:
            //hm
            pthread_mutex_unlock(&x->mutex);
            return 0;
        }
      } else
      {
        //pthread error
        return 0;
      }
    }
    
    ...
    
    void simple_matrix_tilde_oscin(t_simple_matrix_tilde *x, t_symbol *s)
    {
      if(strlen(s->s_name) >= TRANSM_SIZE)
      {
        //sometimes the size is for some reason larger, maybe UDP? crazy guy
        //char recv[TRANSM_SIZE]; //snad to nevybouchne
        memcpy(x->recv, s->s_name, TRANSM_SIZE);
      
        x->val = x->recv[0] - '0';
        x->posx = x->recv[1] - '0';
        x->posy = x->recv[2] - '0';
      
        //post("val %d posx %d posy %d", x->val, x->posx, x->posy);
    
        matrix_rw(x, 1, 3, x->posx, x->posy, x->val); //write
      } else 
      {
        //?
      }
    }
    
    ...
    
    t_int *simple_matrix_tilde_perform(t_int *w)
    {
      t_simple_matrix_tilde *x =  (t_simple_matrix_tilde*)(w[1]);
      t_sample *sig_in =          (t_sample *)(w[2]);
      t_sample *sig_out =         (t_sample *)(w[3]);
      int len =                   (int)(w[4]); //lenght of sample
    
      t_float stat = matrix_rw(x, 0, 2, 0, 0); //read
      for(int u = 0; u < len; u++)
      {
        *sig_out++ = *(sig_in++) * stat;
      }
    
      return (w+5);
    }
    
    ...
    

    posted in extra~ read more
  • kroklop92217

    @robertesler thanks! i tried connecting just symbol object to the inlet instead of the OSC data stream and it works just fine...! so now i need to figure out whats up with the data its receiving. anyways thanks much again

    posted in extra~ read more
  • kroklop92217

    @whale-av thanks much! went through the code and its waayyyy too complex for my current understandig to be helpful. im definitely going to read throug it later when i have time, buut im now im looking for some simple fix to my problem (even something bit dirty).

    posted in extra~ read more
  • kroklop92217

    Hi,
    im trying to implement this simple object/class, that takes symbol in the first inlet and based on its value gates signal from nd inlet to outlet. The symbol comes from udp data stream, that is being parsed as OSC. Internally the incoming signal is multiplied by the symbol value (0 or 1). So in my understanding output should be silent or come through.
    Buuut its not working as excpected... signal output is terribly noisy and "laggy" sounding. Sometimes the puredata even shows and "Audio error". Interestingly, when i stop the OSC transmission it goes to normal and sounds as expected.

    Is my understanding of signal manipulation wrong? Or is the datastream lagging Pd?

    Thanks much for advice!

    simple_matrix~.c

    //sudo ln /Applications/Pd-0.55-0.app/Contents/Resources/src/m_pd.h m_pd.h
    //snad je to ok udelat takhle no
    
    #include <m_pd.h>
    #include <string.h>
    
    
    #define MATRIX_SIZE 7
    #define TRANSM_SIZE 3
    
    
    static t_class *simple_matrix_tilde_class;
    
    typedef struct _simple_matrix_tilde
    {
      t_object x_obj;
    
      t_float m_state[MATRIX_SIZE][MATRIX_SIZE]; //stav peč desky
    
      t_symbol transm_in;
    
      t_inlet *sig_one_in, *sig_two_in, *sig_tri_in, *sig_qud_in, *sig_fiv_in, *sig_six_in, *sig_sev_in; 
      t_outlet *sig_one_out, *sig_two_out, *sig_tri_out, *sig_qud_out, *sig_fiv_out, *sig_six_out, *sig_sev_out;
    
    } t_simple_matrix_tilde;
    
    void simple_matrix_tilde_osc_recv(t_simple_matrix_tilde *x, t_symbol *s)
    {
      if(strlen(s->s_name) > TRANSM_SIZE)
      {
        //pd_error(&x->x_obj, ":(");
        //sometimes the size is for some reason larger, maybe UDP? crazy guy
      }
    
      //post("lenght %d", strlen(s->s_name));
      //post("value %s", s->s_name);
    
      char recv[TRANSM_SIZE]; //snad to nevybouchne
      memcpy(recv, s->s_name, TRANSM_SIZE);
    
      int val = recv[0] - '0';
      int posx = recv[1] - '0';
      int posy = recv[2] - '0';
    
      //post("val %d posx %d posy %d", val, posx, posy);
    
      x->m_state[posx][posy] = (t_float)val;
    }
    
    t_int *simple_matrix_tilde_perform(t_int *w)
    {
      t_simple_matrix_tilde *x =  (t_simple_matrix_tilde*)(w[1]);
      t_sample *sig_in =          (t_sample *)(w[2]);
      t_sample *sig_out =         (t_sample *)(w[3]);
      int len =                   (int)(w[4]); //lenght of sample
    
      for(int u = 0; u < len; u++)
      {
        t_sample timesby = x->m_state[0][0];
        *sig_out++ = *(sig_in++) * timesby;
      }
    
      return (w+5);
    }
    
    void simple_matrix_tilde_dsp(t_simple_matrix_tilde *x, t_signal **sp)
    {
      dsp_add(simple_matrix_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
      return;
    }
    
    void *simple_matrix_tilde_new(void)
    {
      t_simple_matrix_tilde *x = (t_simple_matrix_tilde *)pd_new(simple_matrix_tilde_class);
    
      //wall,
      //wall,
      x->sig_one_in = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
    
      x->sig_one_out = outlet_new(&x->x_obj, &s_signal);
    
      return (void *) x;
    }
    
    void simple_matrix_tilde_freedom(t_simple_matrix_tilde *x)
    {
      inlet_free(x->sig_one_in);
      outlet_free(x->sig_one_out);
    }
    
    void simple_matrix_tilde_setup(void)
    {
      simple_matrix_tilde_class = class_new(
        gensym("simple_matrix~"),
        (t_newmethod)simple_matrix_tilde_new,
        (t_method)simple_matrix_tilde_freedom,
        sizeof(t_simple_matrix_tilde),
        CLASS_DEFAULT,
        0
      );
    
      class_addsymbol(simple_matrix_tilde_class, simple_matrix_tilde_osc_recv);
    
      class_addmethod(simple_matrix_tilde_class, (t_method)simple_matrix_tilde_dsp, gensym("dsp"), A_CANT, 0);
    
    }
    
    

    The function simple_matrix_tilde_osc_recv just takes the input symbol and updates state of matrix connections, from which the gate of signal is later determined in perform function. The object should have 7 signal inlets and outlets in the future.

    Also i understand, that this could be implemented as a subpatch, but it seemed like good first external, to learn the basics.

    aand my Pd patch for testing:
    obrazek.png

    (i just got into writing externls, so maybe my undertanding of basic Pd internal concepts is little off)

    posted in extra~ read more

Internal error.

Oops! Looks like something went wrong!