Csound Csound-dev Csound-tekno Search About

[Csnd-dev] opcodes that output arrays..

Date2016-01-01 12:47
FromRory Walsh
Subject[Csnd-dev] opcodes that output arrays..
I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like

i1[] testopcode 10

which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.  

#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
} TEST_STRUCT;

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Date2016-01-01 23:52
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
Here it goes. 
arrays.c is your friend.
===========================================================
#include 

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p) 
{
    int  i;
    tabensure(csound, p->outArr,*p->size);
    for(i=0; i < *p->size; i++)
       p->outArr->data[i] = i;
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952 

> On 1 Jan 2016, at 12:47, Rory Walsh  wrote:
> 
> I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like 
> 
> i1[] testopcode 10
> 
> which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.   
> 
> #include 
> 
> typedef struct {
>   OPDS    h;
>   ARRAYDAT* outArr;
> } TEST_STRUCT;
> 
> static int testopcode(CSOUND *csound, TEST_STRUCT* p) 
> {
>     return OK;
> }
> 
> #define S(x)    sizeof(x)
> static OENTRY localops[] = {
>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> };

Date2016-01-02 10:10
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:

error:  Unable to find opcode entry for 'testopcode' with matching argument types:
Found: i[] testopcode i
Line: 9

Yet localops[] looks like this?

static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
};

Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?

On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Here it goes.
arrays.c is your friend.
===========================================================
#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
    int  i;
    tabensure(csound, p->outArr,*p->size);
    for(i=0; i < *p->size; i++)
       p->outArr->data[i] = i;
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>
> i1[] testopcode 10
>
> which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>
> #include <csdl.h>
>
> typedef struct {
>   OPDS    h;
>   ARRAYDAT* outArr;
> } TEST_STRUCT;
>
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>     return OK;
> }
>
> #define S(x)    sizeof(x)
> static OENTRY localops[] = {
>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> };
> LINKAGE


Date2016-01-02 11:16
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
This could be because the plugin is not being loaded and the opcode is not found.

Don't worry about memory management, Csound takes care of it.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:

Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:

error:  Unable to find opcode entry for 'testopcode' with matching argument types:
Found: i[] testopcode i
Line: 9

Yet localops[] looks like this?

static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
};

Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?

On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Here it goes.
arrays.c is your friend.
===========================================================
#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
    int  i;
    tabensure(csound, p->outArr,*p->size);
    for(i=0; i < *p->size; i++)
       p->outArr->data[i] = i;
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>
> i1[] testopcode 10
>
> which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>
> #include <csdl.h>
>
> typedef struct {
>   OPDS    h;
>   ARRAYDAT* outArr;
> } TEST_STRUCT;
>
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>     return OK;
> }
>
> #define S(x)    sizeof(x)
> static OENTRY localops[] = {
>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> };
> LINKAGE


Date2016-01-02 12:02
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source. 

On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
This could be because the plugin is not being loaded and the opcode is not found.

Don't worry about memory management, Csound takes care of it.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:

Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:

error:  Unable to find opcode entry for 'testopcode' with matching argument types:
Found: i[] testopcode i
Line: 9

Yet localops[] looks like this?

static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
};

Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?

On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Here it goes.
arrays.c is your friend.
===========================================================
#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
    int  i;
    tabensure(csound, p->outArr,*p->size);
    for(i=0; i < *p->size; i++)
       p->outArr->data[i] = i;
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>
> i1[] testopcode 10
>
> which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>
> #include <csdl.h>
>
> typedef struct {
>   OPDS    h;
>   ARRAYDAT* outArr;
> } TEST_STRUCT;
>
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>     return OK;
> }
>
> #define S(x)    sizeof(x)
> static OENTRY localops[] = {
>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> };
> LINKAGE



Date2016-01-02 12:20
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
it). 

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:

I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source. 

On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
This could be because the plugin is not being loaded and the opcode is not found.

Don't worry about memory management, Csound takes care of it.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:

Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:

error:  Unable to find opcode entry for 'testopcode' with matching argument types:
Found: i[] testopcode i
Line: 9

Yet localops[] looks like this?

static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
};

Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?

On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Here it goes.
arrays.c is your friend.
===========================================================
#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
    int  i;
    tabensure(csound, p->outArr,*p->size);
    for(i=0; i < *p->size; i++)
       p->outArr->data[i] = i;
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>
> i1[] testopcode 10
>
> which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>
> #include <csdl.h>
>
> typedef struct {
>   OPDS    h;
>   ARRAYDAT* outArr;
> } TEST_STRUCT;
>
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>     return OK;
> }
>
> #define S(x)    sizeof(x)
> static OENTRY localops[] = {
>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> };
> LINKAGE



Date2016-01-02 12:28
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
You mean change this:
 
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);

to

      if (p->data==NULL) p->data = (STRINGDAT*)csound->Calloc(csound, ss);
      else p->data = (STRINGDAT*) csound->ReAlloc(csound, p->data, ss);

That gives me an invalid cast error?


On 2 January 2016 at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
it). 

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:

I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source. 

On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
This could be because the plugin is not being loaded and the opcode is not found.

Don't worry about memory management, Csound takes care of it.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:

Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:

error:  Unable to find opcode entry for 'testopcode' with matching argument types:
Found: i[] testopcode i
Line: 9

Yet localops[] looks like this?

static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
};

Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?

On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Here it goes.
arrays.c is your friend.
===========================================================
#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
    int  i;
    tabensure(csound, p->outArr,*p->size);
    for(i=0; i < *p->size; i++)
       p->outArr->data[i] = i;
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>
> i1[] testopcode 10
>
> which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>
> #include <csdl.h>
>
> typedef struct {
>   OPDS    h;
>   ARRAYDAT* outArr;
> } TEST_STRUCT;
>
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>     return OK;
> }
>
> #define S(x)    sizeof(x)
> static OENTRY localops[] = {
>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> };
> LINKAGE




Date2016-01-02 12:31
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
If you are creating the array, you will need to
allocate memory for stringdat structs and
the memory for each string that us held by them. CS_TYPE needs also to be set.

I am afraid you might need to look into arrays.c, and the other files under Engine/
to understand how the typesystem works.
I don't think there is a quick guide to doing
this at the moment.

We might think of introducing an API for
advanced data types so that opcode 
developers can do this more safely.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
it). 

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:

I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source. 

On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
This could be because the plugin is not being loaded and the opcode is not found.

Don't worry about memory management, Csound takes care of it.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:

Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:

error:  Unable to find opcode entry for 'testopcode' with matching argument types:
Found: i[] testopcode i
Line: 9

Yet localops[] looks like this?

static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
};

Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?

On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Here it goes.
arrays.c is your friend.
===========================================================
#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
    int  i;
    tabensure(csound, p->outArr,*p->size);
    for(i=0; i < *p->size; i++)
       p->outArr->data[i] = i;
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>
> i1[] testopcode 10
>
> which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>
> #include <csdl.h>
>
> typedef struct {
>   OPDS    h;
>   ARRAYDAT* outArr;
> } TEST_STRUCT;
>
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>     return OK;
> }
>
> #define S(x)    sizeof(x)
> static OENTRY localops[] = {
>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> };
> LINKAGE



Date2016-01-02 12:47
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.

On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
If you are creating the array, you will need to
allocate memory for stringdat structs and
the memory for each string that us held by them. CS_TYPE needs also to be set.

I am afraid you might need to look into arrays.c, and the other files under Engine/
to understand how the typesystem works.
I don't think there is a quick guide to doing
this at the moment.

We might think of introducing an API for
advanced data types so that opcode 
developers can do this more safely.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
it). 

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:

I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source. 

On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
This could be because the plugin is not being loaded and the opcode is not found.

Don't worry about memory management, Csound takes care of it.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:

Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:

error:  Unable to find opcode entry for 'testopcode' with matching argument types:
Found: i[] testopcode i
Line: 9

Yet localops[] looks like this?

static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
};

Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?

On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Here it goes.
arrays.c is your friend.
===========================================================
#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
    int  i;
    tabensure(csound, p->outArr,*p->size);
    for(i=0; i < *p->size; i++)
       p->outArr->data[i] = i;
    return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
  { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>
> i1[] testopcode 10
>
> which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>
> #include <csdl.h>
>
> typedef struct {
>   OPDS    h;
>   ARRAYDAT* outArr;
> } TEST_STRUCT;
>
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>     return OK;
> }
>
> #define S(x)    sizeof(x)
> static OENTRY localops[] = {
>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> };
> LINKAGE




Date2016-01-02 12:54
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
No, that’s not as simple as that. The tabensure code is for numeric scalar arrays, so it’s
not going to be easily modifiable for strings. 

I suggest you look at the array_init() code, which is used to create arrays of any types.
The CS_TYPE will be already defined by the type of array the code is using, so it’s
set for you. Once you allocate the memory as in that function, you can cast the
arraydat->data to STRINGDAT, and use it:

STRINGDAT *array_data =  (STRINGDAT *) arr->data;

array_data[0].size (size of string)
array_data[0].data   (string data pointer)
...

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952 

> On 2 Jan 2016, at 12:28, Rory Walsh  wrote:
> 
> You mean change this:
>  
>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> 
> to
> 
>       if (p->data==NULL) p->data = (STRINGDAT*)csound->Calloc(csound, ss);
>       else p->data = (STRINGDAT*) csound->ReAlloc(csound, p->data, ss);
> 
> That gives me an invalid cast error? 
> 
> 
> On 2 January 2016 at 12:20, Victor Lazzarini  wrote:
> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> it). 
> 
> Victor Lazzarini
> Dean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland
> 
> On 2 Jan 2016, at 12:02, Rory Walsh  wrote:
> 
>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.  
>> 
>> On 2 January 2016 at 11:16, Victor Lazzarini  wrote:
>> This could be because the plugin is not being loaded and the opcode is not found.
>> 
>> Don't worry about memory management, Csound takes care of it.
>> 
>> Victor Lazzarini
>> Dean of Arts, Celtic Studies, and Philosophy
>> Maynooth University
>> Ireland
>> 
>> On 2 Jan 2016, at 10:10, Rory Walsh  wrote:
>> 
>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
>>> 
>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
>>> Found: i[] testopcode i
>>> Line: 9
>>> 
>>> Yet localops[] looks like this?
>>> 
>>> static OENTRY localops[] = {
>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
>>> };
>>> 
>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards? 
>>> 
>>> On 1 January 2016 at 23:52, Victor Lazzarini  wrote:
>>> Here it goes.
>>> arrays.c is your friend.
>>> ===========================================================
>>> #include 
>>> 
>>> typedef struct {
>>>   OPDS    h;
>>>   ARRAYDAT* outArr;
>>>   MYFLT *size;
>>> } TEST_STRUCT;
>>> 
>>> /* from opcodes/arrays.c */
>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
>>> {
>>>     if (p->data==NULL || p->dimensions == 0 ||
>>>         (p->dimensions==1 && p->sizes[0] < size)) {
>>>       size_t ss;
>>>       if (p->data == NULL) {
>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
>>>         p->arrayMemberSize = var->memBlockSize;
>>>       }
>>> 
>>>       ss = p->arrayMemberSize*size;
>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
>>>       p->dimensions = 1;
>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
>>>       p->sizes[0] = size;
>>>   }
>>> }
>>> 
>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>> {
>>>     int  i;
>>>     tabensure(csound, p->outArr,*p->size);
>>>     for(i=0; i < *p->size; i++)
>>>        p->outArr->data[i] = i;
>>>     return OK;
>>> }
>>> 
>>> #define S(x)    sizeof(x)
>>> static OENTRY localops[] = {
>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
>>> };
>>> LINKAGE
>>> 
>>> 
>>> ========================
>>> Dr Victor Lazzarini
>>> Dean of Arts, Celtic Studies and Philosophy,
>>> Maynooth University,
>>> Maynooth, Co Kildare, Ireland
>>> Tel: 00 353 7086936
>>> Fax: 00 353 1 7086952
>>> 
>>> > On 1 Jan 2016, at 12:47, Rory Walsh  wrote:
>>> >
>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>>> >
>>> > i1[] testopcode 10
>>> >
>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>>> >
>>> > #include 
>>> >
>>> > typedef struct {
>>> >   OPDS    h;
>>> >   ARRAYDAT* outArr;
>>> > } TEST_STRUCT;
>>> >
>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>> > {
>>> >     return OK;
>>> > }
>>> >
>>> > #define S(x)    sizeof(x)
>>> > static OENTRY localops[] = {
>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
>>> > };
>>> > LINKAGE
>>> 
>> 

Date2016-01-02 12:56
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
No comments means you should read the code not the comments. It’s deliberate.
I’ll try to put together an example.

Victor
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952 

> On 2 Jan 2016, at 12:47, Rory Walsh  wrote:
> 
> Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help. 
> 
> On 2 January 2016 at 12:31, Victor Lazzarini  wrote:
> If you are creating the array, you will need to
> allocate memory for stringdat structs and
> the memory for each string that us held by them. CS_TYPE needs also to be set.
> 
> I am afraid you might need to look into arrays.c, and the other files under Engine/
> to understand how the typesystem works.
> I don't think there is a quick guide to doing
> this at the moment.
> 
> We might think of introducing an API for
> advanced data types so that opcode 
> developers can do this more safely.
> 
> Victor Lazzarini
> Dean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland
> 
> On 2 Jan 2016, at 12:20, Victor Lazzarini  wrote:
> 
>> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
>> it). 
>> 
>> Victor Lazzarini
>> Dean of Arts, Celtic Studies, and Philosophy
>> Maynooth University
>> Ireland
>> 
>> On 2 Jan 2016, at 12:02, Rory Walsh  wrote:
>> 
>>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.  
>>> 
>>> On 2 January 2016 at 11:16, Victor Lazzarini  wrote:
>>> This could be because the plugin is not being loaded and the opcode is not found.
>>> 
>>> Don't worry about memory management, Csound takes care of it.
>>> 
>>> Victor Lazzarini
>>> Dean of Arts, Celtic Studies, and Philosophy
>>> Maynooth University
>>> Ireland
>>> 
>>> On 2 Jan 2016, at 10:10, Rory Walsh  wrote:
>>> 
>>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
>>>> 
>>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
>>>> Found: i[] testopcode i
>>>> Line: 9
>>>> 
>>>> Yet localops[] looks like this?
>>>> 
>>>> static OENTRY localops[] = {
>>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
>>>> };
>>>> 
>>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards? 
>>>> 
>>>> On 1 January 2016 at 23:52, Victor Lazzarini  wrote:
>>>> Here it goes.
>>>> arrays.c is your friend.
>>>> ===========================================================
>>>> #include 
>>>> 
>>>> typedef struct {
>>>>   OPDS    h;
>>>>   ARRAYDAT* outArr;
>>>>   MYFLT *size;
>>>> } TEST_STRUCT;
>>>> 
>>>> /* from opcodes/arrays.c */
>>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
>>>> {
>>>>     if (p->data==NULL || p->dimensions == 0 ||
>>>>         (p->dimensions==1 && p->sizes[0] < size)) {
>>>>       size_t ss;
>>>>       if (p->data == NULL) {
>>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
>>>>         p->arrayMemberSize = var->memBlockSize;
>>>>       }
>>>> 
>>>>       ss = p->arrayMemberSize*size;
>>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
>>>>       p->dimensions = 1;
>>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
>>>>       p->sizes[0] = size;
>>>>   }
>>>> }
>>>> 
>>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> {
>>>>     int  i;
>>>>     tabensure(csound, p->outArr,*p->size);
>>>>     for(i=0; i < *p->size; i++)
>>>>        p->outArr->data[i] = i;
>>>>     return OK;
>>>> }
>>>> 
>>>> #define S(x)    sizeof(x)
>>>> static OENTRY localops[] = {
>>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
>>>> };
>>>> LINKAGE
>>>> 
>>>> 
>>>> ========================
>>>> Dr Victor Lazzarini
>>>> Dean of Arts, Celtic Studies and Philosophy,
>>>> Maynooth University,
>>>> Maynooth, Co Kildare, Ireland
>>>> Tel: 00 353 7086936
>>>> Fax: 00 353 1 7086952
>>>> 
>>>> > On 1 Jan 2016, at 12:47, Rory Walsh  wrote:
>>>> >
>>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>>>> >
>>>> > i1[] testopcode 10
>>>> >
>>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>>>> >
>>>> > #include 
>>>> >
>>>> > typedef struct {
>>>> >   OPDS    h;
>>>> >   ARRAYDAT* outArr;
>>>> > } TEST_STRUCT;
>>>> >
>>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> > {
>>>> >     return OK;
>>>> > }
>>>> >
>>>> > #define S(x)    sizeof(x)
>>>> > static OENTRY localops[] = {
>>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
>>>> > };
>>>> > LINKAGE
>>>> 
>>> 

Date2016-01-02 13:08
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Thanks Victor. I'll keep at it. 

On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
No comments means you should read the code not the comments. It’s deliberate.
I’ll try to put together an example.

Victor
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
>
> Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
>
> On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> If you are creating the array, you will need to
> allocate memory for stringdat structs and
> the memory for each string that us held by them. CS_TYPE needs also to be set.
>
> I am afraid you might need to look into arrays.c, and the other files under Engine/
> to understand how the typesystem works.
> I don't think there is a quick guide to doing
> this at the moment.
>
> We might think of introducing an API for
> advanced data types so that opcode
> developers can do this more safely.
>
> Victor Lazzarini
> Dean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland
>
> On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>
>> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
>> it).
>>
>> Victor Lazzarini
>> Dean of Arts, Celtic Studies, and Philosophy
>> Maynooth University
>> Ireland
>>
>> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
>>
>>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
>>>
>>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>> This could be because the plugin is not being loaded and the opcode is not found.
>>>
>>> Don't worry about memory management, Csound takes care of it.
>>>
>>> Victor Lazzarini
>>> Dean of Arts, Celtic Studies, and Philosophy
>>> Maynooth University
>>> Ireland
>>>
>>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
>>>
>>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
>>>>
>>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
>>>> Found: i[] testopcode i
>>>> Line: 9
>>>>
>>>> Yet localops[] looks like this?
>>>>
>>>> static OENTRY localops[] = {
>>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
>>>> };
>>>>
>>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
>>>>
>>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> Here it goes.
>>>> arrays.c is your friend.
>>>> ===========================================================
>>>> #include <csdl.h>
>>>>
>>>> typedef struct {
>>>>   OPDS    h;
>>>>   ARRAYDAT* outArr;
>>>>   MYFLT *size;
>>>> } TEST_STRUCT;
>>>>
>>>> /* from opcodes/arrays.c */
>>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
>>>> {
>>>>     if (p->data==NULL || p->dimensions == 0 ||
>>>>         (p->dimensions==1 && p->sizes[0] < size)) {
>>>>       size_t ss;
>>>>       if (p->data == NULL) {
>>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
>>>>         p->arrayMemberSize = var->memBlockSize;
>>>>       }
>>>>
>>>>       ss = p->arrayMemberSize*size;
>>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
>>>>       p->dimensions = 1;
>>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
>>>>       p->sizes[0] = size;
>>>>   }
>>>> }
>>>>
>>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> {
>>>>     int  i;
>>>>     tabensure(csound, p->outArr,*p->size);
>>>>     for(i=0; i < *p->size; i++)
>>>>        p->outArr->data[i] = i;
>>>>     return OK;
>>>> }
>>>>
>>>> #define S(x)    sizeof(x)
>>>> static OENTRY localops[] = {
>>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
>>>> };
>>>> LINKAGE
>>>>
>>>>
>>>> ========================
>>>> Dr Victor Lazzarini
>>>> Dean of Arts, Celtic Studies and Philosophy,
>>>> Maynooth University,
>>>> Maynooth, Co Kildare, Ireland
>>>> Tel: 00 353 7086936
>>>> Fax: 00 353 1 7086952
>>>>
>>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> >
>>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>>>> >
>>>> > i1[] testopcode 10
>>>> >
>>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>>>> >
>>>> > #include <csdl.h>
>>>> >
>>>> > typedef struct {
>>>> >   OPDS    h;
>>>> >   ARRAYDAT* outArr;
>>>> > } TEST_STRUCT;
>>>> >
>>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> > {
>>>> >     return OK;
>>>> > }
>>>> >
>>>> > #define S(x)    sizeof(x)
>>>> > static OENTRY localops[] = {
>>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
>>>> > };
>>>> > LINKAGE
>>>>
>>>
>


Date2016-01-02 14:36
Fromjpff
SubjectRe: [Csnd-dev] opcodes that output arrays..
There is some creation of string arrays in OSC.c but i failed to 
understand the type bit so it may be wrong.

re comments: my de facto PhD supervisor always said one should not comment 
code as it led people to believe the comments rather than the code.  He 
did it too.  Our flagship algebra system, written in a numeric assembler, had 
2 comments; one said "print" and the other "start here".  Seemed sane to 
me but not his policy on labels -- use none just relative jumps.  Mind you 
he could add code and adjust on a line-editor single pass.
   Labels only appeared after losing the source and Steve Bourne wrote a 
disassembler to recover soures, which generated labels.  Hapy days!

On Sat, 2 Jan 2016, Rory Walsh wrote:

> Thanks Victor. I think I may wait until such an API is developed. Looking
> through the source code is frightening. No a comment to be found! On top of
> that, I can't think of a single existing opcode that outputs a string array.
> No worries. Thanks for the help.
> 
> On 2 January 2016 at 12:31, Victor Lazzarini  wrote:
>       If you are creating the array, you will need to
> allocate memory for stringdat structs and
> the memory for each string that us held by them. CS_TYPE needs also to
> be set.
> 
> I am afraid you might need to look into arrays.c, and the other files
> under Engine/
> to understand how the typesystem works.
> I don't think there is a quick guide to doing
> this at the moment.
> 
> We might think of introducing an API for
> advanced data types so that opcode 
> developers can do this more safely.
> 
> Victor LazzariniDean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland

Date2016-01-02 17:15
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Thanks John, I'll take a look. The problem for me is more to do with the fact that it's pure C rather than what I'm used to. Just makes it more fun I guess?!

On 2 January 2016 at 14:36, jpff <jpff@codemist.co.uk> wrote:
There is some creation of string arrays in OSC.c but i failed to understand the type bit so it may be wrong.

re comments: my de facto PhD supervisor always said one should not comment code as it led people to believe the comments rather than the code.  He did it too.  Our flagship algebra system, written in a numeric assembler, had 2 comments; one said "print" and the other "start here".  Seemed sane to me but not his policy on labels -- use none just relative jumps.  Mind you he could add code and adjust on a line-editor single pass.
  Labels only appeared after losing the source and Steve Bourne wrote a disassembler to recover soures, which generated labels.  Hapy days!

On Sat, 2 Jan 2016, Rory Walsh wrote:

Thanks Victor. I think I may wait until such an API is developed. Looking
through the source code is frightening. No a comment to be found! On top of
that, I can't think of a single existing opcode that outputs a string array.
No worries. Thanks for the help.

On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
      If you are creating the array, you will need to
allocate memory for stringdat structs and
the memory for each string that us held by them. CS_TYPE needs also to
be set.

I am afraid you might need to look into arrays.c, and the other files
under Engine/
to understand how the typesystem works.
I don't think there is a quick guide to doing
this at the moment.

We might think of introducing an API for
advanced data types so that opcode 
developers can do this more safely.

Victor LazzariniDean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland


Date2016-01-02 17:31
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
Are you used to an impure form of it?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 2 Jan 2016, at 17:15, Rory Walsh <rorywalsh@EAR.IE> wrote:

Thanks John, I'll take a look. The problem for me is more to do with the fact that it's pure C rather than what I'm used to. Just makes it more fun I guess?!

On 2 January 2016 at 14:36, jpff <jpff@codemist.co.uk> wrote:
There is some creation of string arrays in OSC.c but i failed to understand the type bit so it may be wrong.

re comments: my de facto PhD supervisor always said one should not comment code as it led people to believe the comments rather than the code.  He did it too.  Our flagship algebra system, written in a numeric assembler, had 2 comments; one said "print" and the other "start here".  Seemed sane to me but not his policy on labels -- use none just relative jumps.  Mind you he could add code and adjust on a line-editor single pass.
  Labels only appeared after losing the source and Steve Bourne wrote a disassembler to recover soures, which generated labels.  Hapy days!

On Sat, 2 Jan 2016, Rory Walsh wrote:

Thanks Victor. I think I may wait until such an API is developed. Looking
through the source code is frightening. No a comment to be found! On top of
that, I can't think of a single existing opcode that outputs a string array.
No worries. Thanks for the help.

On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
      If you are creating the array, you will need to
allocate memory for stringdat structs and
the memory for each string that us held by them. CS_TYPE needs also to
be set.

I am afraid you might need to look into arrays.c, and the other files
under Engine/
to understand how the typesystem works.
I don't think there is a quick guide to doing
this at the moment.

We might think of introducing an API for
advanced data types so that opcode 
developers can do this more safely.

Victor LazzariniDean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland


Date2016-01-02 18:20
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
Actually, I was wrong, tabensure() is generic and will create any array type for you, so
a little modification to my earlier code creates an array of empty strings:

=========
static int testopcode(CSOUND *csound, TEST_STRUCT* p) 
{
   int  i;
   tabensure(csound, p->outArr,*p->size);
   STRINGDAT *strings = (STRINGDAT *) p->outArr->data;

  /* this might not be necessary but it shows what STRINGDATS
     are made of  */
   for(i=0; i < *p->size; i++){
          strings[i].size = 0;
	  strings[i].data = NULL;
   }
   return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE
==========
test code:

 instr 1
Sarr[] testopcode 2
Sarr[0] = "test\n"
Sarr[1] = "now \n"
prints Sarr[0]
prints Sarr[1]
endin

=========

Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
than I made it look.

Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
CSOUND structure, as it looks to be useful in a generic way.

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952 

> On 2 Jan 2016, at 13:08, Rory Walsh  wrote:
> 
> Thanks Victor. I'll keep at it. 
> 
> On 2 January 2016 at 12:56, Victor Lazzarini  wrote:
> No comments means you should read the code not the comments. It’s deliberate.
> I’ll try to put together an example.
> 
> Victor
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
> 
> > On 2 Jan 2016, at 12:47, Rory Walsh  wrote:
> >
> > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> >
> > On 2 January 2016 at 12:31, Victor Lazzarini  wrote:
> > If you are creating the array, you will need to
> > allocate memory for stringdat structs and
> > the memory for each string that us held by them. CS_TYPE needs also to be set.
> >
> > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > to understand how the typesystem works.
> > I don't think there is a quick guide to doing
> > this at the moment.
> >
> > We might think of introducing an API for
> > advanced data types so that opcode
> > developers can do this more safely.
> >
> > Victor Lazzarini
> > Dean of Arts, Celtic Studies, and Philosophy
> > Maynooth University
> > Ireland
> >
> > On 2 Jan 2016, at 12:20, Victor Lazzarini  wrote:
> >
> >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> >> it).
> >>
> >> Victor Lazzarini
> >> Dean of Arts, Celtic Studies, and Philosophy
> >> Maynooth University
> >> Ireland
> >>
> >> On 2 Jan 2016, at 12:02, Rory Walsh  wrote:
> >>
> >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> >>>
> >>> On 2 January 2016 at 11:16, Victor Lazzarini  wrote:
> >>> This could be because the plugin is not being loaded and the opcode is not found.
> >>>
> >>> Don't worry about memory management, Csound takes care of it.
> >>>
> >>> Victor Lazzarini
> >>> Dean of Arts, Celtic Studies, and Philosophy
> >>> Maynooth University
> >>> Ireland
> >>>
> >>> On 2 Jan 2016, at 10:10, Rory Walsh  wrote:
> >>>
> >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> >>>>
> >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> >>>> Found: i[] testopcode i
> >>>> Line: 9
> >>>>
> >>>> Yet localops[] looks like this?
> >>>>
> >>>> static OENTRY localops[] = {
> >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> >>>> };
> >>>>
> >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> >>>>
> >>>> On 1 January 2016 at 23:52, Victor Lazzarini  wrote:
> >>>> Here it goes.
> >>>> arrays.c is your friend.
> >>>> ===========================================================
> >>>> #include 
> >>>>
> >>>> typedef struct {
> >>>>   OPDS    h;
> >>>>   ARRAYDAT* outArr;
> >>>>   MYFLT *size;
> >>>> } TEST_STRUCT;
> >>>>
> >>>> /* from opcodes/arrays.c */
> >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> >>>> {
> >>>>     if (p->data==NULL || p->dimensions == 0 ||
> >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> >>>>       size_t ss;
> >>>>       if (p->data == NULL) {
> >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> >>>>         p->arrayMemberSize = var->memBlockSize;
> >>>>       }
> >>>>
> >>>>       ss = p->arrayMemberSize*size;
> >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> >>>>       p->dimensions = 1;
> >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> >>>>       p->sizes[0] = size;
> >>>>   }
> >>>> }
> >>>>
> >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >>>> {
> >>>>     int  i;
> >>>>     tabensure(csound, p->outArr,*p->size);
> >>>>     for(i=0; i < *p->size; i++)
> >>>>        p->outArr->data[i] = i;
> >>>>     return OK;
> >>>> }
> >>>>
> >>>> #define S(x)    sizeof(x)
> >>>> static OENTRY localops[] = {
> >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> >>>> };
> >>>> LINKAGE
> >>>>
> >>>>
> >>>> ========================
> >>>> Dr Victor Lazzarini
> >>>> Dean of Arts, Celtic Studies and Philosophy,
> >>>> Maynooth University,
> >>>> Maynooth, Co Kildare, Ireland
> >>>> Tel: 00 353 7086936
> >>>> Fax: 00 353 1 7086952
> >>>>
> >>>> > On 1 Jan 2016, at 12:47, Rory Walsh  wrote:
> >>>> >
> >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> >>>> >
> >>>> > i1[] testopcode 10
> >>>> >
> >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> >>>> >
> >>>> > #include 
> >>>> >
> >>>> > typedef struct {
> >>>> >   OPDS    h;
> >>>> >   ARRAYDAT* outArr;
> >>>> > } TEST_STRUCT;
> >>>> >
> >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >>>> > {
> >>>> >     return OK;
> >>>> > }
> >>>> >
> >>>> > #define S(x)    sizeof(x)
> >>>> > static OENTRY localops[] = {
> >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> >>>> > };
> >>>> > LINKAGE
> >>>>
> >>>
> >

Date2016-01-03 10:10
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:

0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
6  0x00000000004017d1  main     

On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Actually, I was wrong, tabensure() is generic and will create any array type for you, so
a little modification to my earlier code creates an array of empty strings:

=========
static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
   int  i;
   tabensure(csound, p->outArr,*p->size);
   STRINGDAT *strings = (STRINGDAT *) p->outArr->data;

  /* this might not be necessary but it shows what STRINGDATS
     are made of  */
   for(i=0; i < *p->size; i++){
          strings[i].size = 0;
          strings[i].data = NULL;
   }
   return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE
==========
test code:

 instr 1
Sarr[] testopcode 2
Sarr[0] = "test\n"
Sarr[1] = "now \n"
prints Sarr[0]
prints Sarr[1]
endin

=========

Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
than I made it look.

Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
CSOUND structure, as it looks to be useful in a generic way.

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> Thanks Victor. I'll keep at it.
>
> On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> No comments means you should read the code not the comments. It’s deliberate.
> I’ll try to put together an example.
>
> Victor
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >
> > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> >
> > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > If you are creating the array, you will need to
> > allocate memory for stringdat structs and
> > the memory for each string that us held by them. CS_TYPE needs also to be set.
> >
> > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > to understand how the typesystem works.
> > I don't think there is a quick guide to doing
> > this at the moment.
> >
> > We might think of introducing an API for
> > advanced data types so that opcode
> > developers can do this more safely.
> >
> > Victor Lazzarini
> > Dean of Arts, Celtic Studies, and Philosophy
> > Maynooth University
> > Ireland
> >
> > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >
> >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> >> it).
> >>
> >> Victor Lazzarini
> >> Dean of Arts, Celtic Studies, and Philosophy
> >> Maynooth University
> >> Ireland
> >>
> >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >>
> >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> >>>
> >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >>> This could be because the plugin is not being loaded and the opcode is not found.
> >>>
> >>> Don't worry about memory management, Csound takes care of it.
> >>>
> >>> Victor Lazzarini
> >>> Dean of Arts, Celtic Studies, and Philosophy
> >>> Maynooth University
> >>> Ireland
> >>>
> >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >>>
> >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> >>>>
> >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> >>>> Found: i[] testopcode i
> >>>> Line: 9
> >>>>
> >>>> Yet localops[] looks like this?
> >>>>
> >>>> static OENTRY localops[] = {
> >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> >>>> };
> >>>>
> >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> >>>>
> >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >>>> Here it goes.
> >>>> arrays.c is your friend.
> >>>> ===========================================================
> >>>> #include <csdl.h>
> >>>>
> >>>> typedef struct {
> >>>>   OPDS    h;
> >>>>   ARRAYDAT* outArr;
> >>>>   MYFLT *size;
> >>>> } TEST_STRUCT;
> >>>>
> >>>> /* from opcodes/arrays.c */
> >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> >>>> {
> >>>>     if (p->data==NULL || p->dimensions == 0 ||
> >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> >>>>       size_t ss;
> >>>>       if (p->data == NULL) {
> >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> >>>>         p->arrayMemberSize = var->memBlockSize;
> >>>>       }
> >>>>
> >>>>       ss = p->arrayMemberSize*size;
> >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> >>>>       p->dimensions = 1;
> >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> >>>>       p->sizes[0] = size;
> >>>>   }
> >>>> }
> >>>>
> >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >>>> {
> >>>>     int  i;
> >>>>     tabensure(csound, p->outArr,*p->size);
> >>>>     for(i=0; i < *p->size; i++)
> >>>>        p->outArr->data[i] = i;
> >>>>     return OK;
> >>>> }
> >>>>
> >>>> #define S(x)    sizeof(x)
> >>>> static OENTRY localops[] = {
> >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> >>>> };
> >>>> LINKAGE
> >>>>
> >>>>
> >>>> ========================
> >>>> Dr Victor Lazzarini
> >>>> Dean of Arts, Celtic Studies and Philosophy,
> >>>> Maynooth University,
> >>>> Maynooth, Co Kildare, Ireland
> >>>> Tel: 00 353 7086936
> >>>> Fax: 00 353 1 7086952
> >>>>
> >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> >>>> >
> >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> >>>> >
> >>>> > i1[] testopcode 10
> >>>> >
> >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> >>>> >
> >>>> > #include <csdl.h>
> >>>> >
> >>>> > typedef struct {
> >>>> >   OPDS    h;
> >>>> >   ARRAYDAT* outArr;
> >>>> > } TEST_STRUCT;
> >>>> >
> >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >>>> > {
> >>>> >     return OK;
> >>>> > }
> >>>> >
> >>>> > #define S(x)    sizeof(x)
> >>>> > static OENTRY localops[] = {
> >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> >>>> > };
> >>>> > LINKAGE
> >>>>
> >>>
> >
>


Date2016-01-03 12:06
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
I don't know, it works here. I will have a look.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:

Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:

0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
6  0x00000000004017d1  main     

On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Actually, I was wrong, tabensure() is generic and will create any array type for you, so
a little modification to my earlier code creates an array of empty strings:

=========
static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
   int  i;
   tabensure(csound, p->outArr,*p->size);
   STRINGDAT *strings = (STRINGDAT *) p->outArr->data;

  /* this might not be necessary but it shows what STRINGDATS
     are made of  */
   for(i=0; i < *p->size; i++){
          strings[i].size = 0;
          strings[i].data = NULL;
   }
   return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE
==========
test code:

 instr 1
Sarr[] testopcode 2
Sarr[0] = "test\n"
Sarr[1] = "now \n"
prints Sarr[0]
prints Sarr[1]
endin

=========

Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
than I made it look.

Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
CSOUND structure, as it looks to be useful in a generic way.

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> Thanks Victor. I'll keep at it.
>
> On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> No comments means you should read the code not the comments. It’s deliberate.
> I’ll try to put together an example.
>
> Victor
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >
> > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> >
> > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > If you are creating the array, you will need to
> > allocate memory for stringdat structs and
> > the memory for each string that us held by them. CS_TYPE needs also to be set.
> >
> > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > to understand how the typesystem works.
> > I don't think there is a quick guide to doing
> > this at the moment.
> >
> > We might think of introducing an API for
> > advanced data types so that opcode
> > developers can do this more safely.
> >
> > Victor Lazzarini
> > Dean of Arts, Celtic Studies, and Philosophy
> > Maynooth University
> > Ireland
> >
> > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >
> >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> >> it).
> >>
> >> Victor Lazzarini
> >> Dean of Arts, Celtic Studies, and Philosophy
> >> Maynooth University
> >> Ireland
> >>
> >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >>
> >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> >>>
> >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >>> This could be because the plugin is not being loaded and the opcode is not found.
> >>>
> >>> Don't worry about memory management, Csound takes care of it.
> >>>
> >>> Victor Lazzarini
> >>> Dean of Arts, Celtic Studies, and Philosophy
> >>> Maynooth University
> >>> Ireland
> >>>
> >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >>>
> >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> >>>>
> >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> >>>> Found: i[] testopcode i
> >>>> Line: 9
> >>>>
> >>>> Yet localops[] looks like this?
> >>>>
> >>>> static OENTRY localops[] = {
> >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> >>>> };
> >>>>
> >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> >>>>
> >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >>>> Here it goes.
> >>>> arrays.c is your friend.
> >>>> ===========================================================
> >>>> #include <csdl.h>
> >>>>
> >>>> typedef struct {
> >>>>   OPDS    h;
> >>>>   ARRAYDAT* outArr;
> >>>>   MYFLT *size;
> >>>> } TEST_STRUCT;
> >>>>
> >>>> /* from opcodes/arrays.c */
> >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> >>>> {
> >>>>     if (p->data==NULL || p->dimensions == 0 ||
> >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> >>>>       size_t ss;
> >>>>       if (p->data == NULL) {
> >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> >>>>         p->arrayMemberSize = var->memBlockSize;
> >>>>       }
> >>>>
> >>>>       ss = p->arrayMemberSize*size;
> >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> >>>>       p->dimensions = 1;
> >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> >>>>       p->sizes[0] = size;
> >>>>   }
> >>>> }
> >>>>
> >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >>>> {
> >>>>     int  i;
> >>>>     tabensure(csound, p->outArr,*p->size);
> >>>>     for(i=0; i < *p->size; i++)
> >>>>        p->outArr->data[i] = i;
> >>>>     return OK;
> >>>> }
> >>>>
> >>>> #define S(x)    sizeof(x)
> >>>> static OENTRY localops[] = {
> >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> >>>> };
> >>>> LINKAGE
> >>>>
> >>>>
> >>>> ========================
> >>>> Dr Victor Lazzarini
> >>>> Dean of Arts, Celtic Studies and Philosophy,
> >>>> Maynooth University,
> >>>> Maynooth, Co Kildare, Ireland
> >>>> Tel: 00 353 7086936
> >>>> Fax: 00 353 1 7086952
> >>>>
> >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> >>>> >
> >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> >>>> >
> >>>> > i1[] testopcode 10
> >>>> >
> >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> >>>> >
> >>>> > #include <csdl.h>
> >>>> >
> >>>> > typedef struct {
> >>>> >   OPDS    h;
> >>>> >   ARRAYDAT* outArr;
> >>>> > } TEST_STRUCT;
> >>>> >
> >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >>>> > {
> >>>> >     return OK;
> >>>> > }
> >>>> >
> >>>> > #define S(x)    sizeof(x)
> >>>> > static OENTRY localops[] = {
> >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> >>>> > };
> >>>> > LINKAGE
> >>>>
> >>>
> >
>


Date2016-01-03 12:09
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Perhaps a platform issue? I take it you're on OSX?

On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
I don't know, it works here. I will have a look.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:

Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:

0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
6  0x00000000004017d1  main     

On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Actually, I was wrong, tabensure() is generic and will create any array type for you, so
a little modification to my earlier code creates an array of empty strings:

=========
static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
   int  i;
   tabensure(csound, p->outArr,*p->size);
   STRINGDAT *strings = (STRINGDAT *) p->outArr->data;

  /* this might not be necessary but it shows what STRINGDATS
     are made of  */
   for(i=0; i < *p->size; i++){
          strings[i].size = 0;
          strings[i].data = NULL;
   }
   return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE
==========
test code:

 instr 1
Sarr[] testopcode 2
Sarr[0] = "test\n"
Sarr[1] = "now \n"
prints Sarr[0]
prints Sarr[1]
endin

=========

Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
than I made it look.

Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
CSOUND structure, as it looks to be useful in a generic way.

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> Thanks Victor. I'll keep at it.
>
> On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> No comments means you should read the code not the comments. It’s deliberate.
> I’ll try to put together an example.
>
> Victor
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >
> > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> >
> > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > If you are creating the array, you will need to
> > allocate memory for stringdat structs and
> > the memory for each string that us held by them. CS_TYPE needs also to be set.
> >
> > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > to understand how the typesystem works.
> > I don't think there is a quick guide to doing
> > this at the moment.
> >
> > We might think of introducing an API for
> > advanced data types so that opcode
> > developers can do this more safely.
> >
> > Victor Lazzarini
> > Dean of Arts, Celtic Studies, and Philosophy
> > Maynooth University
> > Ireland
> >
> > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >
> >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> >> it).
> >>
> >> Victor Lazzarini
> >> Dean of Arts, Celtic Studies, and Philosophy
> >> Maynooth University
> >> Ireland
> >>
> >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >>
> >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> >>>
> >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >>> This could be because the plugin is not being loaded and the opcode is not found.
> >>>
> >>> Don't worry about memory management, Csound takes care of it.
> >>>
> >>> Victor Lazzarini
> >>> Dean of Arts, Celtic Studies, and Philosophy
> >>> Maynooth University
> >>> Ireland
> >>>
> >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >>>
> >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> >>>>
> >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> >>>> Found: i[] testopcode i
> >>>> Line: 9
> >>>>
> >>>> Yet localops[] looks like this?
> >>>>
> >>>> static OENTRY localops[] = {
> >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> >>>> };
> >>>>
> >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> >>>>
> >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >>>> Here it goes.
> >>>> arrays.c is your friend.
> >>>> ===========================================================
> >>>> #include <csdl.h>
> >>>>
> >>>> typedef struct {
> >>>>   OPDS    h;
> >>>>   ARRAYDAT* outArr;
> >>>>   MYFLT *size;
> >>>> } TEST_STRUCT;
> >>>>
> >>>> /* from opcodes/arrays.c */
> >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> >>>> {
> >>>>     if (p->data==NULL || p->dimensions == 0 ||
> >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> >>>>       size_t ss;
> >>>>       if (p->data == NULL) {
> >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> >>>>         p->arrayMemberSize = var->memBlockSize;
> >>>>       }
> >>>>
> >>>>       ss = p->arrayMemberSize*size;
> >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> >>>>       p->dimensions = 1;
> >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> >>>>       p->sizes[0] = size;
> >>>>   }
> >>>> }
> >>>>
> >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >>>> {
> >>>>     int  i;
> >>>>     tabensure(csound, p->outArr,*p->size);
> >>>>     for(i=0; i < *p->size; i++)
> >>>>        p->outArr->data[i] = i;
> >>>>     return OK;
> >>>> }
> >>>>
> >>>> #define S(x)    sizeof(x)
> >>>> static OENTRY localops[] = {
> >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> >>>> };
> >>>> LINKAGE
> >>>>
> >>>>
> >>>> ========================
> >>>> Dr Victor Lazzarini
> >>>> Dean of Arts, Celtic Studies and Philosophy,
> >>>> Maynooth University,
> >>>> Maynooth, Co Kildare, Ireland
> >>>> Tel: 00 353 7086936
> >>>> Fax: 00 353 1 7086952
> >>>>
> >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> >>>> >
> >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> >>>> >
> >>>> > i1[] testopcode 10
> >>>> >
> >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> >>>> >
> >>>> > #include <csdl.h>
> >>>> >
> >>>> > typedef struct {
> >>>> >   OPDS    h;
> >>>> >   ARRAYDAT* outArr;
> >>>> > } TEST_STRUCT;
> >>>> >
> >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >>>> > {
> >>>> >     return OK;
> >>>> > }
> >>>> >
> >>>> > #define S(x)    sizeof(x)
> >>>> > static OENTRY localops[] = {
> >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> >>>> > };
> >>>> > LINKAGE
> >>>>
> >>>
> >
>



Date2016-01-03 12:47
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
yes. I checked under the debugger, there does not seem to be any problem. The code looks
correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952 

> On 3 Jan 2016, at 12:09, Rory Walsh  wrote:
> 
> Perhaps a platform issue? I take it you're on OSX?
> 
> On 3 January 2016 at 12:06, Victor Lazzarini  wrote:
> I don't know, it works here. I will have a look.
> 
> Victor Lazzarini
> Dean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland
> 
> On 3 Jan 2016, at 10:10, Rory Walsh  wrote:
> 
>> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
>> 
>> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
>> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
>> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
>> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
>> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
>> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
>> 6  0x00000000004017d1  main      
>> 
>> On 2 January 2016 at 18:20, Victor Lazzarini  wrote:
>> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
>> a little modification to my earlier code creates an array of empty strings:
>> 
>> =========
>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> {
>>    int  i;
>>    tabensure(csound, p->outArr,*p->size);
>>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
>> 
>>   /* this might not be necessary but it shows what STRINGDATS
>>      are made of  */
>>    for(i=0; i < *p->size; i++){
>>           strings[i].size = 0;
>>           strings[i].data = NULL;
>>    }
>>    return OK;
>> }
>> 
>> #define S(x)    sizeof(x)
>> static OENTRY localops[] = {
>>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
>> };
>> LINKAGE
>> ==========
>> test code:
>> 
>>  instr 1
>> Sarr[] testopcode 2
>> Sarr[0] = "test\n"
>> Sarr[1] = "now \n"
>> prints Sarr[0]
>> prints Sarr[1]
>> endin
>> 
>> =========
>> 
>> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
>> than I made it look.
>> 
>> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
>> CSOUND structure, as it looks to be useful in a generic way.
>> 
>> ========================
>> Dr Victor Lazzarini
>> Dean of Arts, Celtic Studies and Philosophy,
>> Maynooth University,
>> Maynooth, Co Kildare, Ireland
>> Tel: 00 353 7086936
>> Fax: 00 353 1 7086952
>> 
>> > On 2 Jan 2016, at 13:08, Rory Walsh  wrote:
>> >
>> > Thanks Victor. I'll keep at it.
>> >
>> > On 2 January 2016 at 12:56, Victor Lazzarini  wrote:
>> > No comments means you should read the code not the comments. It’s deliberate.
>> > I’ll try to put together an example.
>> >
>> > Victor
>> > ========================
>> > Dr Victor Lazzarini
>> > Dean of Arts, Celtic Studies and Philosophy,
>> > Maynooth University,
>> > Maynooth, Co Kildare, Ireland
>> > Tel: 00 353 7086936
>> > Fax: 00 353 1 7086952
>> >
>> > > On 2 Jan 2016, at 12:47, Rory Walsh  wrote:
>> > >
>> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
>> > >
>> > > On 2 January 2016 at 12:31, Victor Lazzarini  wrote:
>> > > If you are creating the array, you will need to
>> > > allocate memory for stringdat structs and
>> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
>> > >
>> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
>> > > to understand how the typesystem works.
>> > > I don't think there is a quick guide to doing
>> > > this at the moment.
>> > >
>> > > We might think of introducing an API for
>> > > advanced data types so that opcode
>> > > developers can do this more safely.
>> > >
>> > > Victor Lazzarini
>> > > Dean of Arts, Celtic Studies, and Philosophy
>> > > Maynooth University
>> > > Ireland
>> > >
>> > > On 2 Jan 2016, at 12:20, Victor Lazzarini  wrote:
>> > >
>> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
>> > >> it).
>> > >>
>> > >> Victor Lazzarini
>> > >> Dean of Arts, Celtic Studies, and Philosophy
>> > >> Maynooth University
>> > >> Ireland
>> > >>
>> > >> On 2 Jan 2016, at 12:02, Rory Walsh  wrote:
>> > >>
>> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
>> > >>>
>> > >>> On 2 January 2016 at 11:16, Victor Lazzarini  wrote:
>> > >>> This could be because the plugin is not being loaded and the opcode is not found.
>> > >>>
>> > >>> Don't worry about memory management, Csound takes care of it.
>> > >>>
>> > >>> Victor Lazzarini
>> > >>> Dean of Arts, Celtic Studies, and Philosophy
>> > >>> Maynooth University
>> > >>> Ireland
>> > >>>
>> > >>> On 2 Jan 2016, at 10:10, Rory Walsh  wrote:
>> > >>>
>> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
>> > >>>>
>> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
>> > >>>> Found: i[] testopcode i
>> > >>>> Line: 9
>> > >>>>
>> > >>>> Yet localops[] looks like this?
>> > >>>>
>> > >>>> static OENTRY localops[] = {
>> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
>> > >>>> };
>> > >>>>
>> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
>> > >>>>
>> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini  wrote:
>> > >>>> Here it goes.
>> > >>>> arrays.c is your friend.
>> > >>>> ===========================================================
>> > >>>> #include 
>> > >>>>
>> > >>>> typedef struct {
>> > >>>>   OPDS    h;
>> > >>>>   ARRAYDAT* outArr;
>> > >>>>   MYFLT *size;
>> > >>>> } TEST_STRUCT;
>> > >>>>
>> > >>>> /* from opcodes/arrays.c */
>> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
>> > >>>> {
>> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
>> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
>> > >>>>       size_t ss;
>> > >>>>       if (p->data == NULL) {
>> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
>> > >>>>         p->arrayMemberSize = var->memBlockSize;
>> > >>>>       }
>> > >>>>
>> > >>>>       ss = p->arrayMemberSize*size;
>> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
>> > >>>>       p->dimensions = 1;
>> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
>> > >>>>       p->sizes[0] = size;
>> > >>>>   }
>> > >>>> }
>> > >>>>
>> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> > >>>> {
>> > >>>>     int  i;
>> > >>>>     tabensure(csound, p->outArr,*p->size);
>> > >>>>     for(i=0; i < *p->size; i++)
>> > >>>>        p->outArr->data[i] = i;
>> > >>>>     return OK;
>> > >>>> }
>> > >>>>
>> > >>>> #define S(x)    sizeof(x)
>> > >>>> static OENTRY localops[] = {
>> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
>> > >>>> };
>> > >>>> LINKAGE
>> > >>>>
>> > >>>>
>> > >>>> ========================
>> > >>>> Dr Victor Lazzarini
>> > >>>> Dean of Arts, Celtic Studies and Philosophy,
>> > >>>> Maynooth University,
>> > >>>> Maynooth, Co Kildare, Ireland
>> > >>>> Tel: 00 353 7086936
>> > >>>> Fax: 00 353 1 7086952
>> > >>>>
>> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh  wrote:
>> > >>>> >
>> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>> > >>>> >
>> > >>>> > i1[] testopcode 10
>> > >>>> >
>> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>> > >>>> >
>> > >>>> > #include 
>> > >>>> >
>> > >>>> > typedef struct {
>> > >>>> >   OPDS    h;
>> > >>>> >   ARRAYDAT* outArr;
>> > >>>> > } TEST_STRUCT;
>> > >>>> >
>> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> > >>>> > {
>> > >>>> >     return OK;
>> > >>>> > }
>> > >>>> >
>> > >>>> > #define S(x)    sizeof(x)
>> > >>>> > static OENTRY localops[] = {
>> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
>> > >>>> > };
>> > >>>> > LINKAGE
>> > >>>>
>> > >>>
>> > >
>> >
>> 

Date2016-01-03 13:06
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.  

On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
yes. I checked under the debugger, there does not seem to be any problem. The code looks
correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> Perhaps a platform issue? I take it you're on OSX?
>
> On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> I don't know, it works here. I will have a look.
>
> Victor Lazzarini
> Dean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland
>
> On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
>
>> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
>>
>> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
>> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
>> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
>> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
>> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
>> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
>> 6  0x00000000004017d1  main
>>
>> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
>> a little modification to my earlier code creates an array of empty strings:
>>
>> =========
>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> {
>>    int  i;
>>    tabensure(csound, p->outArr,*p->size);
>>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
>>
>>   /* this might not be necessary but it shows what STRINGDATS
>>      are made of  */
>>    for(i=0; i < *p->size; i++){
>>           strings[i].size = 0;
>>           strings[i].data = NULL;
>>    }
>>    return OK;
>> }
>>
>> #define S(x)    sizeof(x)
>> static OENTRY localops[] = {
>>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
>> };
>> LINKAGE
>> ==========
>> test code:
>>
>>  instr 1
>> Sarr[] testopcode 2
>> Sarr[0] = "test\n"
>> Sarr[1] = "now \n"
>> prints Sarr[0]
>> prints Sarr[1]
>> endin
>>
>> =========
>>
>> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
>> than I made it look.
>>
>> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
>> CSOUND structure, as it looks to be useful in a generic way.
>>
>> ========================
>> Dr Victor Lazzarini
>> Dean of Arts, Celtic Studies and Philosophy,
>> Maynooth University,
>> Maynooth, Co Kildare, Ireland
>> Tel: 00 353 7086936
>> Fax: 00 353 1 7086952
>>
>> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
>> >
>> > Thanks Victor. I'll keep at it.
>> >
>> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > No comments means you should read the code not the comments. It’s deliberate.
>> > I’ll try to put together an example.
>> >
>> > Victor
>> > ========================
>> > Dr Victor Lazzarini
>> > Dean of Arts, Celtic Studies and Philosophy,
>> > Maynooth University,
>> > Maynooth, Co Kildare, Ireland
>> > Tel: 00 353 7086936
>> > Fax: 00 353 1 7086952
>> >
>> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
>> > >
>> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
>> > >
>> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > > If you are creating the array, you will need to
>> > > allocate memory for stringdat structs and
>> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
>> > >
>> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
>> > > to understand how the typesystem works.
>> > > I don't think there is a quick guide to doing
>> > > this at the moment.
>> > >
>> > > We might think of introducing an API for
>> > > advanced data types so that opcode
>> > > developers can do this more safely.
>> > >
>> > > Victor Lazzarini
>> > > Dean of Arts, Celtic Studies, and Philosophy
>> > > Maynooth University
>> > > Ireland
>> > >
>> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > >
>> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
>> > >> it).
>> > >>
>> > >> Victor Lazzarini
>> > >> Dean of Arts, Celtic Studies, and Philosophy
>> > >> Maynooth University
>> > >> Ireland
>> > >>
>> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
>> > >>
>> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
>> > >>>
>> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > >>> This could be because the plugin is not being loaded and the opcode is not found.
>> > >>>
>> > >>> Don't worry about memory management, Csound takes care of it.
>> > >>>
>> > >>> Victor Lazzarini
>> > >>> Dean of Arts, Celtic Studies, and Philosophy
>> > >>> Maynooth University
>> > >>> Ireland
>> > >>>
>> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
>> > >>>
>> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
>> > >>>>
>> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
>> > >>>> Found: i[] testopcode i
>> > >>>> Line: 9
>> > >>>>
>> > >>>> Yet localops[] looks like this?
>> > >>>>
>> > >>>> static OENTRY localops[] = {
>> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
>> > >>>> };
>> > >>>>
>> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
>> > >>>>
>> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > >>>> Here it goes.
>> > >>>> arrays.c is your friend.
>> > >>>> ===========================================================
>> > >>>> #include <csdl.h>
>> > >>>>
>> > >>>> typedef struct {
>> > >>>>   OPDS    h;
>> > >>>>   ARRAYDAT* outArr;
>> > >>>>   MYFLT *size;
>> > >>>> } TEST_STRUCT;
>> > >>>>
>> > >>>> /* from opcodes/arrays.c */
>> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
>> > >>>> {
>> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
>> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
>> > >>>>       size_t ss;
>> > >>>>       if (p->data == NULL) {
>> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
>> > >>>>         p->arrayMemberSize = var->memBlockSize;
>> > >>>>       }
>> > >>>>
>> > >>>>       ss = p->arrayMemberSize*size;
>> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
>> > >>>>       p->dimensions = 1;
>> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
>> > >>>>       p->sizes[0] = size;
>> > >>>>   }
>> > >>>> }
>> > >>>>
>> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> > >>>> {
>> > >>>>     int  i;
>> > >>>>     tabensure(csound, p->outArr,*p->size);
>> > >>>>     for(i=0; i < *p->size; i++)
>> > >>>>        p->outArr->data[i] = i;
>> > >>>>     return OK;
>> > >>>> }
>> > >>>>
>> > >>>> #define S(x)    sizeof(x)
>> > >>>> static OENTRY localops[] = {
>> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
>> > >>>> };
>> > >>>> LINKAGE
>> > >>>>
>> > >>>>
>> > >>>> ========================
>> > >>>> Dr Victor Lazzarini
>> > >>>> Dean of Arts, Celtic Studies and Philosophy,
>> > >>>> Maynooth University,
>> > >>>> Maynooth, Co Kildare, Ireland
>> > >>>> Tel: 00 353 7086936
>> > >>>> Fax: 00 353 1 7086952
>> > >>>>
>> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>> > >>>> >
>> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>> > >>>> >
>> > >>>> > i1[] testopcode 10
>> > >>>> >
>> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>> > >>>> >
>> > >>>> > #include <csdl.h>
>> > >>>> >
>> > >>>> > typedef struct {
>> > >>>> >   OPDS    h;
>> > >>>> >   ARRAYDAT* outArr;
>> > >>>> > } TEST_STRUCT;
>> > >>>> >
>> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> > >>>> > {
>> > >>>> >     return OK;
>> > >>>> > }
>> > >>>> >
>> > >>>> > #define S(x)    sizeof(x)
>> > >>>> > static OENTRY localops[] = {
>> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
>> > >>>> > };
>> > >>>> > LINKAGE
>> > >>>>
>> > >>>
>> > >
>> >
>>
>


Date2016-01-03 13:14
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.

On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.  

On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
yes. I checked under the debugger, there does not seem to be any problem. The code looks
correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> Perhaps a platform issue? I take it you're on OSX?
>
> On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> I don't know, it works here. I will have a look.
>
> Victor Lazzarini
> Dean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland
>
> On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
>
>> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
>>
>> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
>> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
>> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
>> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
>> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
>> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
>> 6  0x00000000004017d1  main
>>
>> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
>> a little modification to my earlier code creates an array of empty strings:
>>
>> =========
>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> {
>>    int  i;
>>    tabensure(csound, p->outArr,*p->size);
>>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
>>
>>   /* this might not be necessary but it shows what STRINGDATS
>>      are made of  */
>>    for(i=0; i < *p->size; i++){
>>           strings[i].size = 0;
>>           strings[i].data = NULL;
>>    }
>>    return OK;
>> }
>>
>> #define S(x)    sizeof(x)
>> static OENTRY localops[] = {
>>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
>> };
>> LINKAGE
>> ==========
>> test code:
>>
>>  instr 1
>> Sarr[] testopcode 2
>> Sarr[0] = "test\n"
>> Sarr[1] = "now \n"
>> prints Sarr[0]
>> prints Sarr[1]
>> endin
>>
>> =========
>>
>> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
>> than I made it look.
>>
>> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
>> CSOUND structure, as it looks to be useful in a generic way.
>>
>> ========================
>> Dr Victor Lazzarini
>> Dean of Arts, Celtic Studies and Philosophy,
>> Maynooth University,
>> Maynooth, Co Kildare, Ireland
>> Tel: 00 353 7086936
>> Fax: 00 353 1 7086952
>>
>> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
>> >
>> > Thanks Victor. I'll keep at it.
>> >
>> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > No comments means you should read the code not the comments. It’s deliberate.
>> > I’ll try to put together an example.
>> >
>> > Victor
>> > ========================
>> > Dr Victor Lazzarini
>> > Dean of Arts, Celtic Studies and Philosophy,
>> > Maynooth University,
>> > Maynooth, Co Kildare, Ireland
>> > Tel: 00 353 7086936
>> > Fax: 00 353 1 7086952
>> >
>> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
>> > >
>> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
>> > >
>> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > > If you are creating the array, you will need to
>> > > allocate memory for stringdat structs and
>> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
>> > >
>> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
>> > > to understand how the typesystem works.
>> > > I don't think there is a quick guide to doing
>> > > this at the moment.
>> > >
>> > > We might think of introducing an API for
>> > > advanced data types so that opcode
>> > > developers can do this more safely.
>> > >
>> > > Victor Lazzarini
>> > > Dean of Arts, Celtic Studies, and Philosophy
>> > > Maynooth University
>> > > Ireland
>> > >
>> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > >
>> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
>> > >> it).
>> > >>
>> > >> Victor Lazzarini
>> > >> Dean of Arts, Celtic Studies, and Philosophy
>> > >> Maynooth University
>> > >> Ireland
>> > >>
>> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
>> > >>
>> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
>> > >>>
>> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > >>> This could be because the plugin is not being loaded and the opcode is not found.
>> > >>>
>> > >>> Don't worry about memory management, Csound takes care of it.
>> > >>>
>> > >>> Victor Lazzarini
>> > >>> Dean of Arts, Celtic Studies, and Philosophy
>> > >>> Maynooth University
>> > >>> Ireland
>> > >>>
>> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
>> > >>>
>> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
>> > >>>>
>> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
>> > >>>> Found: i[] testopcode i
>> > >>>> Line: 9
>> > >>>>
>> > >>>> Yet localops[] looks like this?
>> > >>>>
>> > >>>> static OENTRY localops[] = {
>> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
>> > >>>> };
>> > >>>>
>> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
>> > >>>>
>> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> > >>>> Here it goes.
>> > >>>> arrays.c is your friend.
>> > >>>> ===========================================================
>> > >>>> #include <csdl.h>
>> > >>>>
>> > >>>> typedef struct {
>> > >>>>   OPDS    h;
>> > >>>>   ARRAYDAT* outArr;
>> > >>>>   MYFLT *size;
>> > >>>> } TEST_STRUCT;
>> > >>>>
>> > >>>> /* from opcodes/arrays.c */
>> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
>> > >>>> {
>> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
>> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
>> > >>>>       size_t ss;
>> > >>>>       if (p->data == NULL) {
>> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
>> > >>>>         p->arrayMemberSize = var->memBlockSize;
>> > >>>>       }
>> > >>>>
>> > >>>>       ss = p->arrayMemberSize*size;
>> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
>> > >>>>       p->dimensions = 1;
>> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
>> > >>>>       p->sizes[0] = size;
>> > >>>>   }
>> > >>>> }
>> > >>>>
>> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> > >>>> {
>> > >>>>     int  i;
>> > >>>>     tabensure(csound, p->outArr,*p->size);
>> > >>>>     for(i=0; i < *p->size; i++)
>> > >>>>        p->outArr->data[i] = i;
>> > >>>>     return OK;
>> > >>>> }
>> > >>>>
>> > >>>> #define S(x)    sizeof(x)
>> > >>>> static OENTRY localops[] = {
>> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
>> > >>>> };
>> > >>>> LINKAGE
>> > >>>>
>> > >>>>
>> > >>>> ========================
>> > >>>> Dr Victor Lazzarini
>> > >>>> Dean of Arts, Celtic Studies and Philosophy,
>> > >>>> Maynooth University,
>> > >>>> Maynooth, Co Kildare, Ireland
>> > >>>> Tel: 00 353 7086936
>> > >>>> Fax: 00 353 1 7086952
>> > >>>>
>> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>> > >>>> >
>> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>> > >>>> >
>> > >>>> > i1[] testopcode 10
>> > >>>> >
>> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>> > >>>> >
>> > >>>> > #include <csdl.h>
>> > >>>> >
>> > >>>> > typedef struct {
>> > >>>> >   OPDS    h;
>> > >>>> >   ARRAYDAT* outArr;
>> > >>>> > } TEST_STRUCT;
>> > >>>> >
>> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>> > >>>> > {
>> > >>>> >     return OK;
>> > >>>> > }
>> > >>>> >
>> > >>>> > #define S(x)    sizeof(x)
>> > >>>> > static OENTRY localops[] = {
>> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
>> > >>>> > };
>> > >>>> > LINKAGE
>> > >>>>
>> > >>>
>> > >
>> >
>>
>



Date2016-01-03 13:30
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
Or if you can run in a debugger, can you check it there?

Did you try running this under the csound command? That’s how I am testing here.

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952 

> On 3 Jan 2016, at 13:14, Rory Walsh  wrote:
> 
> I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell. 
> 
> On 3 January 2016 at 13:06, Rory Walsh  wrote:
> It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.   
> 
> On 3 January 2016 at 12:47, Victor Lazzarini  wrote:
> yes. I checked under the debugger, there does not seem to be any problem. The code looks
> correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
> 
> > On 3 Jan 2016, at 12:09, Rory Walsh  wrote:
> >
> > Perhaps a platform issue? I take it you're on OSX?
> >
> > On 3 January 2016 at 12:06, Victor Lazzarini  wrote:
> > I don't know, it works here. I will have a look.
> >
> > Victor Lazzarini
> > Dean of Arts, Celtic Studies, and Philosophy
> > Maynooth University
> > Ireland
> >
> > On 3 Jan 2016, at 10:10, Rory Walsh  wrote:
> >
> >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> >>
> >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> >> 6  0x00000000004017d1  main
> >>
> >> On 2 January 2016 at 18:20, Victor Lazzarini  wrote:
> >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> >> a little modification to my earlier code creates an array of empty strings:
> >>
> >> =========
> >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> {
> >>    int  i;
> >>    tabensure(csound, p->outArr,*p->size);
> >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> >>
> >>   /* this might not be necessary but it shows what STRINGDATS
> >>      are made of  */
> >>    for(i=0; i < *p->size; i++){
> >>           strings[i].size = 0;
> >>           strings[i].data = NULL;
> >>    }
> >>    return OK;
> >> }
> >>
> >> #define S(x)    sizeof(x)
> >> static OENTRY localops[] = {
> >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> >> };
> >> LINKAGE
> >> ==========
> >> test code:
> >>
> >>  instr 1
> >> Sarr[] testopcode 2
> >> Sarr[0] = "test\n"
> >> Sarr[1] = "now \n"
> >> prints Sarr[0]
> >> prints Sarr[1]
> >> endin
> >>
> >> =========
> >>
> >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> >> than I made it look.
> >>
> >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> >> CSOUND structure, as it looks to be useful in a generic way.
> >>
> >> ========================
> >> Dr Victor Lazzarini
> >> Dean of Arts, Celtic Studies and Philosophy,
> >> Maynooth University,
> >> Maynooth, Co Kildare, Ireland
> >> Tel: 00 353 7086936
> >> Fax: 00 353 1 7086952
> >>
> >> > On 2 Jan 2016, at 13:08, Rory Walsh  wrote:
> >> >
> >> > Thanks Victor. I'll keep at it.
> >> >
> >> > On 2 January 2016 at 12:56, Victor Lazzarini  wrote:
> >> > No comments means you should read the code not the comments. It’s deliberate.
> >> > I’ll try to put together an example.
> >> >
> >> > Victor
> >> > ========================
> >> > Dr Victor Lazzarini
> >> > Dean of Arts, Celtic Studies and Philosophy,
> >> > Maynooth University,
> >> > Maynooth, Co Kildare, Ireland
> >> > Tel: 00 353 7086936
> >> > Fax: 00 353 1 7086952
> >> >
> >> > > On 2 Jan 2016, at 12:47, Rory Walsh  wrote:
> >> > >
> >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> >> > >
> >> > > On 2 January 2016 at 12:31, Victor Lazzarini  wrote:
> >> > > If you are creating the array, you will need to
> >> > > allocate memory for stringdat structs and
> >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> >> > >
> >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> >> > > to understand how the typesystem works.
> >> > > I don't think there is a quick guide to doing
> >> > > this at the moment.
> >> > >
> >> > > We might think of introducing an API for
> >> > > advanced data types so that opcode
> >> > > developers can do this more safely.
> >> > >
> >> > > Victor Lazzarini
> >> > > Dean of Arts, Celtic Studies, and Philosophy
> >> > > Maynooth University
> >> > > Ireland
> >> > >
> >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini  wrote:
> >> > >
> >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> >> > >> it).
> >> > >>
> >> > >> Victor Lazzarini
> >> > >> Dean of Arts, Celtic Studies, and Philosophy
> >> > >> Maynooth University
> >> > >> Ireland
> >> > >>
> >> > >> On 2 Jan 2016, at 12:02, Rory Walsh  wrote:
> >> > >>
> >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> >> > >>>
> >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini  wrote:
> >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> >> > >>>
> >> > >>> Don't worry about memory management, Csound takes care of it.
> >> > >>>
> >> > >>> Victor Lazzarini
> >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> >> > >>> Maynooth University
> >> > >>> Ireland
> >> > >>>
> >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh  wrote:
> >> > >>>
> >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> >> > >>>>
> >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> >> > >>>> Found: i[] testopcode i
> >> > >>>> Line: 9
> >> > >>>>
> >> > >>>> Yet localops[] looks like this?
> >> > >>>>
> >> > >>>> static OENTRY localops[] = {
> >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> >> > >>>> };
> >> > >>>>
> >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> >> > >>>>
> >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini  wrote:
> >> > >>>> Here it goes.
> >> > >>>> arrays.c is your friend.
> >> > >>>> ===========================================================
> >> > >>>> #include 
> >> > >>>>
> >> > >>>> typedef struct {
> >> > >>>>   OPDS    h;
> >> > >>>>   ARRAYDAT* outArr;
> >> > >>>>   MYFLT *size;
> >> > >>>> } TEST_STRUCT;
> >> > >>>>
> >> > >>>> /* from opcodes/arrays.c */
> >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> >> > >>>> {
> >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> >> > >>>>       size_t ss;
> >> > >>>>       if (p->data == NULL) {
> >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> >> > >>>>       }
> >> > >>>>
> >> > >>>>       ss = p->arrayMemberSize*size;
> >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> >> > >>>>       p->dimensions = 1;
> >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> >> > >>>>       p->sizes[0] = size;
> >> > >>>>   }
> >> > >>>> }
> >> > >>>>
> >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> > >>>> {
> >> > >>>>     int  i;
> >> > >>>>     tabensure(csound, p->outArr,*p->size);
> >> > >>>>     for(i=0; i < *p->size; i++)
> >> > >>>>        p->outArr->data[i] = i;
> >> > >>>>     return OK;
> >> > >>>> }
> >> > >>>>
> >> > >>>> #define S(x)    sizeof(x)
> >> > >>>> static OENTRY localops[] = {
> >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> >> > >>>> };
> >> > >>>> LINKAGE
> >> > >>>>
> >> > >>>>
> >> > >>>> ========================
> >> > >>>> Dr Victor Lazzarini
> >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> >> > >>>> Maynooth University,
> >> > >>>> Maynooth, Co Kildare, Ireland
> >> > >>>> Tel: 00 353 7086936
> >> > >>>> Fax: 00 353 1 7086952
> >> > >>>>
> >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh  wrote:
> >> > >>>> >
> >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> >> > >>>> >
> >> > >>>> > i1[] testopcode 10
> >> > >>>> >
> >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> >> > >>>> >
> >> > >>>> > #include 
> >> > >>>> >
> >> > >>>> > typedef struct {
> >> > >>>> >   OPDS    h;
> >> > >>>> >   ARRAYDAT* outArr;
> >> > >>>> > } TEST_STRUCT;
> >> > >>>> >
> >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> > >>>> > {
> >> > >>>> >     return OK;
> >> > >>>> > }
> >> > >>>> >
> >> > >>>> > #define S(x)    sizeof(x)
> >> > >>>> > static OENTRY localops[] = {
> >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> >> > >>>> > };
> >> > >>>> > LINKAGE
> >> > >>>>
> >> > >>>
> >> > >
> >> >
> >>
> >
> 

Date2016-01-03 13:34
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.

==3693== Memcheck, a memory error detector
==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3693== Command: csound ../Opcodes/directory.csd
==3693== Parent PID: 2340
==3693==
==3693== Invalid read of size 8
==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
==3693==    by 0x4FF44CE: reset (csound.c:2961)
==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd

On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
Or if you can run in a debugger, can you check it there?

Did you try running this under the csound command? That’s how I am testing here.

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
>
> On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
>
> On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> yes. I checked under the debugger, there does not seem to be any problem. The code looks
> correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > Perhaps a platform issue? I take it you're on OSX?
> >
> > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > I don't know, it works here. I will have a look.
> >
> > Victor Lazzarini
> > Dean of Arts, Celtic Studies, and Philosophy
> > Maynooth University
> > Ireland
> >
> > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >
> >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> >>
> >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> >> 6  0x00000000004017d1  main
> >>
> >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> >> a little modification to my earlier code creates an array of empty strings:
> >>
> >> =========
> >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> {
> >>    int  i;
> >>    tabensure(csound, p->outArr,*p->size);
> >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> >>
> >>   /* this might not be necessary but it shows what STRINGDATS
> >>      are made of  */
> >>    for(i=0; i < *p->size; i++){
> >>           strings[i].size = 0;
> >>           strings[i].data = NULL;
> >>    }
> >>    return OK;
> >> }
> >>
> >> #define S(x)    sizeof(x)
> >> static OENTRY localops[] = {
> >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> >> };
> >> LINKAGE
> >> ==========
> >> test code:
> >>
> >>  instr 1
> >> Sarr[] testopcode 2
> >> Sarr[0] = "test\n"
> >> Sarr[1] = "now \n"
> >> prints Sarr[0]
> >> prints Sarr[1]
> >> endin
> >>
> >> =========
> >>
> >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> >> than I made it look.
> >>
> >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> >> CSOUND structure, as it looks to be useful in a generic way.
> >>
> >> ========================
> >> Dr Victor Lazzarini
> >> Dean of Arts, Celtic Studies and Philosophy,
> >> Maynooth University,
> >> Maynooth, Co Kildare, Ireland
> >> Tel: 00 353 7086936
> >> Fax: 00 353 1 7086952
> >>
> >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> >> >
> >> > Thanks Victor. I'll keep at it.
> >> >
> >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > No comments means you should read the code not the comments. It’s deliberate.
> >> > I’ll try to put together an example.
> >> >
> >> > Victor
> >> > ========================
> >> > Dr Victor Lazzarini
> >> > Dean of Arts, Celtic Studies and Philosophy,
> >> > Maynooth University,
> >> > Maynooth, Co Kildare, Ireland
> >> > Tel: 00 353 7086936
> >> > Fax: 00 353 1 7086952
> >> >
> >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >
> >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> >> > >
> >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > > If you are creating the array, you will need to
> >> > > allocate memory for stringdat structs and
> >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> >> > >
> >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> >> > > to understand how the typesystem works.
> >> > > I don't think there is a quick guide to doing
> >> > > this at the moment.
> >> > >
> >> > > We might think of introducing an API for
> >> > > advanced data types so that opcode
> >> > > developers can do this more safely.
> >> > >
> >> > > Victor Lazzarini
> >> > > Dean of Arts, Celtic Studies, and Philosophy
> >> > > Maynooth University
> >> > > Ireland
> >> > >
> >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >
> >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> >> > >> it).
> >> > >>
> >> > >> Victor Lazzarini
> >> > >> Dean of Arts, Celtic Studies, and Philosophy
> >> > >> Maynooth University
> >> > >> Ireland
> >> > >>
> >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >>
> >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> >> > >>>
> >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> >> > >>>
> >> > >>> Don't worry about memory management, Csound takes care of it.
> >> > >>>
> >> > >>> Victor Lazzarini
> >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> >> > >>> Maynooth University
> >> > >>> Ireland
> >> > >>>
> >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >>>
> >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> >> > >>>>
> >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> >> > >>>> Found: i[] testopcode i
> >> > >>>> Line: 9
> >> > >>>>
> >> > >>>> Yet localops[] looks like this?
> >> > >>>>
> >> > >>>> static OENTRY localops[] = {
> >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> >> > >>>> };
> >> > >>>>
> >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> >> > >>>>
> >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >>>> Here it goes.
> >> > >>>> arrays.c is your friend.
> >> > >>>> ===========================================================
> >> > >>>> #include <csdl.h>
> >> > >>>>
> >> > >>>> typedef struct {
> >> > >>>>   OPDS    h;
> >> > >>>>   ARRAYDAT* outArr;
> >> > >>>>   MYFLT *size;
> >> > >>>> } TEST_STRUCT;
> >> > >>>>
> >> > >>>> /* from opcodes/arrays.c */
> >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> >> > >>>> {
> >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> >> > >>>>       size_t ss;
> >> > >>>>       if (p->data == NULL) {
> >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> >> > >>>>       }
> >> > >>>>
> >> > >>>>       ss = p->arrayMemberSize*size;
> >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> >> > >>>>       p->dimensions = 1;
> >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> >> > >>>>       p->sizes[0] = size;
> >> > >>>>   }
> >> > >>>> }
> >> > >>>>
> >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> > >>>> {
> >> > >>>>     int  i;
> >> > >>>>     tabensure(csound, p->outArr,*p->size);
> >> > >>>>     for(i=0; i < *p->size; i++)
> >> > >>>>        p->outArr->data[i] = i;
> >> > >>>>     return OK;
> >> > >>>> }
> >> > >>>>
> >> > >>>> #define S(x)    sizeof(x)
> >> > >>>> static OENTRY localops[] = {
> >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> >> > >>>> };
> >> > >>>> LINKAGE
> >> > >>>>
> >> > >>>>
> >> > >>>> ========================
> >> > >>>> Dr Victor Lazzarini
> >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> >> > >>>> Maynooth University,
> >> > >>>> Maynooth, Co Kildare, Ireland
> >> > >>>> Tel: 00 353 7086936
> >> > >>>> Fax: 00 353 1 7086952
> >> > >>>>
> >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> >> > >>>> >
> >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> >> > >>>> >
> >> > >>>> > i1[] testopcode 10
> >> > >>>> >
> >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> >> > >>>> >
> >> > >>>> > #include <csdl.h>
> >> > >>>> >
> >> > >>>> > typedef struct {
> >> > >>>> >   OPDS    h;
> >> > >>>> >   ARRAYDAT* outArr;
> >> > >>>> > } TEST_STRUCT;
> >> > >>>> >
> >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> > >>>> > {
> >> > >>>> >     return OK;
> >> > >>>> > }
> >> > >>>> >
> >> > >>>> > #define S(x)    sizeof(x)
> >> > >>>> > static OENTRY localops[] = {
> >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> >> > >>>> > };
> >> > >>>> > LINKAGE
> >> > >>>>
> >> > >>>
> >> > >
> >> >
> >>
> >
>
>


Date2016-01-03 13:37
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..

On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.

==3693== Memcheck, a memory error detector
==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3693== Command: csound ../Opcodes/directory.csd
==3693== Parent PID: 2340
==3693==
==3693== Invalid read of size 8
==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
==3693==    by 0x4FF44CE: reset (csound.c:2961)
==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd

On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
Or if you can run in a debugger, can you check it there?

Did you try running this under the csound command? That’s how I am testing here.

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
>
> On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
>
> On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> yes. I checked under the debugger, there does not seem to be any problem. The code looks
> correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > Perhaps a platform issue? I take it you're on OSX?
> >
> > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > I don't know, it works here. I will have a look.
> >
> > Victor Lazzarini
> > Dean of Arts, Celtic Studies, and Philosophy
> > Maynooth University
> > Ireland
> >
> > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >
> >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> >>
> >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> >> 6  0x00000000004017d1  main
> >>
> >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> >> a little modification to my earlier code creates an array of empty strings:
> >>
> >> =========
> >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> {
> >>    int  i;
> >>    tabensure(csound, p->outArr,*p->size);
> >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> >>
> >>   /* this might not be necessary but it shows what STRINGDATS
> >>      are made of  */
> >>    for(i=0; i < *p->size; i++){
> >>           strings[i].size = 0;
> >>           strings[i].data = NULL;
> >>    }
> >>    return OK;
> >> }
> >>
> >> #define S(x)    sizeof(x)
> >> static OENTRY localops[] = {
> >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> >> };
> >> LINKAGE
> >> ==========
> >> test code:
> >>
> >>  instr 1
> >> Sarr[] testopcode 2
> >> Sarr[0] = "test\n"
> >> Sarr[1] = "now \n"
> >> prints Sarr[0]
> >> prints Sarr[1]
> >> endin
> >>
> >> =========
> >>
> >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> >> than I made it look.
> >>
> >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> >> CSOUND structure, as it looks to be useful in a generic way.
> >>
> >> ========================
> >> Dr Victor Lazzarini
> >> Dean of Arts, Celtic Studies and Philosophy,
> >> Maynooth University,
> >> Maynooth, Co Kildare, Ireland
> >> Tel: 00 353 7086936
> >> Fax: 00 353 1 7086952
> >>
> >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> >> >
> >> > Thanks Victor. I'll keep at it.
> >> >
> >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > No comments means you should read the code not the comments. It’s deliberate.
> >> > I’ll try to put together an example.
> >> >
> >> > Victor
> >> > ========================
> >> > Dr Victor Lazzarini
> >> > Dean of Arts, Celtic Studies and Philosophy,
> >> > Maynooth University,
> >> > Maynooth, Co Kildare, Ireland
> >> > Tel: 00 353 7086936
> >> > Fax: 00 353 1 7086952
> >> >
> >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >
> >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> >> > >
> >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > > If you are creating the array, you will need to
> >> > > allocate memory for stringdat structs and
> >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> >> > >
> >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> >> > > to understand how the typesystem works.
> >> > > I don't think there is a quick guide to doing
> >> > > this at the moment.
> >> > >
> >> > > We might think of introducing an API for
> >> > > advanced data types so that opcode
> >> > > developers can do this more safely.
> >> > >
> >> > > Victor Lazzarini
> >> > > Dean of Arts, Celtic Studies, and Philosophy
> >> > > Maynooth University
> >> > > Ireland
> >> > >
> >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >
> >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> >> > >> it).
> >> > >>
> >> > >> Victor Lazzarini
> >> > >> Dean of Arts, Celtic Studies, and Philosophy
> >> > >> Maynooth University
> >> > >> Ireland
> >> > >>
> >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >>
> >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> >> > >>>
> >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> >> > >>>
> >> > >>> Don't worry about memory management, Csound takes care of it.
> >> > >>>
> >> > >>> Victor Lazzarini
> >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> >> > >>> Maynooth University
> >> > >>> Ireland
> >> > >>>
> >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >>>
> >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> >> > >>>>
> >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> >> > >>>> Found: i[] testopcode i
> >> > >>>> Line: 9
> >> > >>>>
> >> > >>>> Yet localops[] looks like this?
> >> > >>>>
> >> > >>>> static OENTRY localops[] = {
> >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> >> > >>>> };
> >> > >>>>
> >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> >> > >>>>
> >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >>>> Here it goes.
> >> > >>>> arrays.c is your friend.
> >> > >>>> ===========================================================
> >> > >>>> #include <csdl.h>
> >> > >>>>
> >> > >>>> typedef struct {
> >> > >>>>   OPDS    h;
> >> > >>>>   ARRAYDAT* outArr;
> >> > >>>>   MYFLT *size;
> >> > >>>> } TEST_STRUCT;
> >> > >>>>
> >> > >>>> /* from opcodes/arrays.c */
> >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> >> > >>>> {
> >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> >> > >>>>       size_t ss;
> >> > >>>>       if (p->data == NULL) {
> >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> >> > >>>>       }
> >> > >>>>
> >> > >>>>       ss = p->arrayMemberSize*size;
> >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> >> > >>>>       p->dimensions = 1;
> >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> >> > >>>>       p->sizes[0] = size;
> >> > >>>>   }
> >> > >>>> }
> >> > >>>>
> >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> > >>>> {
> >> > >>>>     int  i;
> >> > >>>>     tabensure(csound, p->outArr,*p->size);
> >> > >>>>     for(i=0; i < *p->size; i++)
> >> > >>>>        p->outArr->data[i] = i;
> >> > >>>>     return OK;
> >> > >>>> }
> >> > >>>>
> >> > >>>> #define S(x)    sizeof(x)
> >> > >>>> static OENTRY localops[] = {
> >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> >> > >>>> };
> >> > >>>> LINKAGE
> >> > >>>>
> >> > >>>>
> >> > >>>> ========================
> >> > >>>> Dr Victor Lazzarini
> >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> >> > >>>> Maynooth University,
> >> > >>>> Maynooth, Co Kildare, Ireland
> >> > >>>> Tel: 00 353 7086936
> >> > >>>> Fax: 00 353 1 7086952
> >> > >>>>
> >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> >> > >>>> >
> >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> >> > >>>> >
> >> > >>>> > i1[] testopcode 10
> >> > >>>> >
> >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> >> > >>>> >
> >> > >>>> > #include <csdl.h>
> >> > >>>> >
> >> > >>>> > typedef struct {
> >> > >>>> >   OPDS    h;
> >> > >>>> >   ARRAYDAT* outArr;
> >> > >>>> > } TEST_STRUCT;
> >> > >>>> >
> >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> > >>>> > {
> >> > >>>> >     return OK;
> >> > >>>> > }
> >> > >>>> >
> >> > >>>> > #define S(x)    sizeof(x)
> >> > >>>> > static OENTRY localops[] = {
> >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> >> > >>>> > };
> >> > >>>> > LINKAGE
> >> > >>>>
> >> > >>>
> >> > >
> >> >
> >>
> >
>
>



Date2016-01-03 13:45
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.

On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..

On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.

==3693== Memcheck, a memory error detector
==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3693== Command: csound ../Opcodes/directory.csd
==3693== Parent PID: 2340
==3693==
==3693== Invalid read of size 8
==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
==3693==    by 0x4FF44CE: reset (csound.c:2961)
==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd

On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
Or if you can run in a debugger, can you check it there?

Did you try running this under the csound command? That’s how I am testing here.

========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
>
> On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
>
> On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> yes. I checked under the debugger, there does not seem to be any problem. The code looks
> correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > Perhaps a platform issue? I take it you're on OSX?
> >
> > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > I don't know, it works here. I will have a look.
> >
> > Victor Lazzarini
> > Dean of Arts, Celtic Studies, and Philosophy
> > Maynooth University
> > Ireland
> >
> > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >
> >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> >>
> >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> >> 6  0x00000000004017d1  main
> >>
> >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> >> a little modification to my earlier code creates an array of empty strings:
> >>
> >> =========
> >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> {
> >>    int  i;
> >>    tabensure(csound, p->outArr,*p->size);
> >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> >>
> >>   /* this might not be necessary but it shows what STRINGDATS
> >>      are made of  */
> >>    for(i=0; i < *p->size; i++){
> >>           strings[i].size = 0;
> >>           strings[i].data = NULL;
> >>    }
> >>    return OK;
> >> }
> >>
> >> #define S(x)    sizeof(x)
> >> static OENTRY localops[] = {
> >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> >> };
> >> LINKAGE
> >> ==========
> >> test code:
> >>
> >>  instr 1
> >> Sarr[] testopcode 2
> >> Sarr[0] = "test\n"
> >> Sarr[1] = "now \n"
> >> prints Sarr[0]
> >> prints Sarr[1]
> >> endin
> >>
> >> =========
> >>
> >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> >> than I made it look.
> >>
> >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> >> CSOUND structure, as it looks to be useful in a generic way.
> >>
> >> ========================
> >> Dr Victor Lazzarini
> >> Dean of Arts, Celtic Studies and Philosophy,
> >> Maynooth University,
> >> Maynooth, Co Kildare, Ireland
> >> Tel: 00 353 7086936
> >> Fax: 00 353 1 7086952
> >>
> >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> >> >
> >> > Thanks Victor. I'll keep at it.
> >> >
> >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > No comments means you should read the code not the comments. It’s deliberate.
> >> > I’ll try to put together an example.
> >> >
> >> > Victor
> >> > ========================
> >> > Dr Victor Lazzarini
> >> > Dean of Arts, Celtic Studies and Philosophy,
> >> > Maynooth University,
> >> > Maynooth, Co Kildare, Ireland
> >> > Tel: 00 353 7086936
> >> > Fax: 00 353 1 7086952
> >> >
> >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >
> >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> >> > >
> >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > > If you are creating the array, you will need to
> >> > > allocate memory for stringdat structs and
> >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> >> > >
> >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> >> > > to understand how the typesystem works.
> >> > > I don't think there is a quick guide to doing
> >> > > this at the moment.
> >> > >
> >> > > We might think of introducing an API for
> >> > > advanced data types so that opcode
> >> > > developers can do this more safely.
> >> > >
> >> > > Victor Lazzarini
> >> > > Dean of Arts, Celtic Studies, and Philosophy
> >> > > Maynooth University
> >> > > Ireland
> >> > >
> >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >
> >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> >> > >> it).
> >> > >>
> >> > >> Victor Lazzarini
> >> > >> Dean of Arts, Celtic Studies, and Philosophy
> >> > >> Maynooth University
> >> > >> Ireland
> >> > >>
> >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >>
> >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> >> > >>>
> >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> >> > >>>
> >> > >>> Don't worry about memory management, Csound takes care of it.
> >> > >>>
> >> > >>> Victor Lazzarini
> >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> >> > >>> Maynooth University
> >> > >>> Ireland
> >> > >>>
> >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> >> > >>>
> >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> >> > >>>>
> >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> >> > >>>> Found: i[] testopcode i
> >> > >>>> Line: 9
> >> > >>>>
> >> > >>>> Yet localops[] looks like this?
> >> > >>>>
> >> > >>>> static OENTRY localops[] = {
> >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> >> > >>>> };
> >> > >>>>
> >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> >> > >>>>
> >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> >> > >>>> Here it goes.
> >> > >>>> arrays.c is your friend.
> >> > >>>> ===========================================================
> >> > >>>> #include <csdl.h>
> >> > >>>>
> >> > >>>> typedef struct {
> >> > >>>>   OPDS    h;
> >> > >>>>   ARRAYDAT* outArr;
> >> > >>>>   MYFLT *size;
> >> > >>>> } TEST_STRUCT;
> >> > >>>>
> >> > >>>> /* from opcodes/arrays.c */
> >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> >> > >>>> {
> >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> >> > >>>>       size_t ss;
> >> > >>>>       if (p->data == NULL) {
> >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> >> > >>>>       }
> >> > >>>>
> >> > >>>>       ss = p->arrayMemberSize*size;
> >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> >> > >>>>       p->dimensions = 1;
> >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> >> > >>>>       p->sizes[0] = size;
> >> > >>>>   }
> >> > >>>> }
> >> > >>>>
> >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> > >>>> {
> >> > >>>>     int  i;
> >> > >>>>     tabensure(csound, p->outArr,*p->size);
> >> > >>>>     for(i=0; i < *p->size; i++)
> >> > >>>>        p->outArr->data[i] = i;
> >> > >>>>     return OK;
> >> > >>>> }
> >> > >>>>
> >> > >>>> #define S(x)    sizeof(x)
> >> > >>>> static OENTRY localops[] = {
> >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> >> > >>>> };
> >> > >>>> LINKAGE
> >> > >>>>
> >> > >>>>
> >> > >>>> ========================
> >> > >>>> Dr Victor Lazzarini
> >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> >> > >>>> Maynooth University,
> >> > >>>> Maynooth, Co Kildare, Ireland
> >> > >>>> Tel: 00 353 7086936
> >> > >>>> Fax: 00 353 1 7086952
> >> > >>>>
> >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> >> > >>>> >
> >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> >> > >>>> >
> >> > >>>> > i1[] testopcode 10
> >> > >>>> >
> >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> >> > >>>> >
> >> > >>>> > #include <csdl.h>
> >> > >>>> >
> >> > >>>> > typedef struct {
> >> > >>>> >   OPDS    h;
> >> > >>>> >   ARRAYDAT* outArr;
> >> > >>>> > } TEST_STRUCT;
> >> > >>>> >
> >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> >> > >>>> > {
> >> > >>>> >     return OK;
> >> > >>>> > }
> >> > >>>> >
> >> > >>>> > #define S(x)    sizeof(x)
> >> > >>>> > static OENTRY localops[] = {
> >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> >> > >>>> > };
> >> > >>>> > LINKAGE
> >> > >>>>
> >> > >>>
> >> > >
> >> >
> >>
> >
>
>




Date2016-01-03 13:59
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952 

> On 3 Jan 2016, at 13:45, Rory Walsh  wrote:
> 
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier. 
> 
> On 3 January 2016 at 13:37, Rory Walsh  wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
> 
> On 3 January 2016 at 13:34, Rory Walsh  wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps. 
> 
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693== 
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
> 
> On 3 January 2016 at 13:30, Victor Lazzarini  wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
> 
> Did you try running this under the csound command? That’s how I am testing here.
> 
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
> 
> > On 3 Jan 2016, at 13:14, Rory Walsh  wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh  wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini  wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh  wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini  wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh  wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini  wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh  wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini  wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh  wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini  wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini  wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh  wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini  wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh  wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini  wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include 
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh  wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include 
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
> 
> 

Date2016-01-03 14:38
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>


Date2016-01-03 14:45
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>


Date2016-01-03 14:55
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
I simply passed a size of 2.

On 3 January 2016 at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>



Date2016-01-03 15:00
Fromjpff
SubjectRe: [Csnd-dev] opcodes that output arrays..
I am late to your issues; I guess I ought to write a docuent on the array 
structure.  That is the relatoinship between dimension, size and data. 
Would that help ot do you know that now?

Date2016-01-03 15:03
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
I'm starting to get it now alright. Victor's simple code example from earlier was extremely useful, although I can't explain why we were seeing those segfaults.

On 3 January 2016 at 15:00, jpff <jpff@codemist.co.uk> wrote:
I am late to your issues; I guess I ought to write a docuent on the array structure.  That is the relatoinship between dimension, size and data. Would that help ot do you know that now?
==John


Date2016-01-03 15:11
FromSteven Yi
SubjectRe: [Csnd-dev] opcodes that output arrays..
Apologies, I haven't been following this thread closely myself but
just took a look. This error:

==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)

makes me think that the STRINGDAT passed in to be freed is NULL.

Rory: could you post the complete code somewhere to view?

On Sun, Jan 3, 2016 at 7:00 AM, jpff  wrote:
> I am late to your issues; I guess I ought to write a docuent on the array
> structure.  That is the relatoinship between dimension, size and data. Would
> that help ot do you know that now?

Date2016-01-03 15:17
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Here you go, it' basically the code Victor posted, but here is the full code, and Csound instrument below to test.

#include <csdl.h>

typedef struct {
  OPDS    h;
  ARRAYDAT* outArr;
  MYFLT *size;
} TEST_STRUCT;

/* from opcodes/arrays.c */
static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
{
    if (p->data==NULL || p->dimensions == 0 ||
        (p->dimensions==1 && p->sizes[0] < size)) {
      size_t ss;
      if (p->data == NULL) {
        CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
        p->arrayMemberSize = var->memBlockSize;
      }

      ss = p->arrayMemberSize*size;
      if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
      else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
      p->dimensions = 1;
      p->sizes = (int*)csound->Malloc(csound, sizeof(int));
      p->sizes[0] = size;
  }
}

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
   int  i;
   tabensure(csound, p->outArr,*p->size);
   STRINGDAT *strings = (STRINGDAT *) p->outArr->data;

  /* this might not be necessary but it shows what STRINGDATS
     are made of  */
   for(i=0; i < *p->size; i++){
          strings[i].size = 0;
          strings[i].data = NULL;
   }
   return OK;
}

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE


//============== INSTRUMENT ==================
/*

<CsoundSynthesizer>
<CsOptions>
-+rtaudio=alsa -odac -b4096
</CsOptions>
<CsInstruments>

instr 1
Sarr[] testopcode 2
Sarr[0] = "test\n"
Sarr[1] = "now \n"
prints Sarr[0]
prints Sarr[1]
endin

</CsInstruments>
<CsScore>
i1 0 30
</CsScore>
</CsoundSynthesiser>

*/

On 3 January 2016 at 15:11, Steven Yi <stevenyi@gmail.com> wrote:
Apologies, I haven't been following this thread closely myself but
just took a look. This error:

==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)

makes me think that the STRINGDAT passed in to be freed is NULL.

Rory: could you post the complete code somewhere to view?

On Sun, Jan 3, 2016 at 7:00 AM, jpff <jpff@codemist.co.uk> wrote:
> I am late to your issues; I guess I ought to write a docuent on the array
> structure.  That is the relatoinship between dimension, size and data. Would
> that help ot do you know that now?
> ==John


Date2016-01-03 15:23
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.



Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>


Date2016-01-03 15:23
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
Look my email & csd test example.

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

> On 3 Jan 2016, at 15:11, Steven Yi  wrote:
> 
> Apologies, I haven't been following this thread closely myself but
> just took a look. This error:
> 
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> 
> makes me think that the STRINGDAT passed in to be freed is NULL.
> 
> Rory: could you post the complete code somewhere to view?
> 
>> On Sun, Jan 3, 2016 at 7:00 AM, jpff  wrote:
>> I am late to your issues; I guess I ought to write a docuent on the array
>> structure.  That is the relatoinship between dimension, size and data. Would
>> that help ot do you know that now?

Date2016-01-03 15:33
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
It turns out that I had a typo in the call to make_plugin(), after I fixed this your example runs without a problem. So, as you do, I did a make clean, and added the typo back in and wouldn't you know, it still runs fine! What on earth could be going on here? I didn't change anything in the code. I'm gong to see if I can recreate the problem somehow.

On 3 January 2016 at 15:23, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.



Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>



Date2016-01-03 15:43
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Ok, some further digging around and it seems that I have a libopcodetest.so in my build folder that make clean was not getting rid of. My incorrectly spelled by most up to date libopcdetest.so uses is almost identical apart from having different input types in its OENTRY structure. But the opcode name was the same in each. I imagine that when Csound starts loading the plugin opcodes it was loads both of them and that was leading to problem. Good God. What a mess. Apologies all around. I better come up with something useful after all of this! 

On 3 January 2016 at 15:33, Rory Walsh <rorywalsh@ear.ie> wrote:
It turns out that I had a typo in the call to make_plugin(), after I fixed this your example runs without a problem. So, as you do, I did a make clean, and added the typo back in and wouldn't you know, it still runs fine! What on earth could be going on here? I didn't change anything in the code. I'm gong to see if I can recreate the problem somehow.

On 3 January 2016 at 15:23, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.



Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>




Date2016-01-03 16:03
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
I'm not sure I follow. Neither was *size in your example? It's a MYFLT*, what different would swapping that out for a 2 make? As in:

tabensure(csound, p->outArr, 2);

Or perhaps I misunderstood your origin question?



On 3 January 2016 at 15:23, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.



Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>



Date2016-01-03 16:07
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
the S type would not match 2 as a parameter to the opcode and csound should have given a syntax error

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 16:03, Rory Walsh <rorywalsh@EAR.IE> wrote:

I'm not sure I follow. Neither was *size in your example? It's a MYFLT*, what different would swapping that out for a 2 make? As in:

tabensure(csound, p->outArr, 2);

Or perhaps I misunderstood your origin question?



On 3 January 2016 at 15:23, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.



Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>



Date2016-01-03 16:20
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Ok, I see now where the confusion is coming from. I didn't pass 2 as the array size in my opcode. I simply passed a 2 as the size parameter to the tabensure() function as in my previously quoted code.

On 3 January 2016 at 16:07, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
the S type would not match 2 as a parameter to the opcode and csound should have given a syntax error

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 16:03, Rory Walsh <rorywalsh@EAR.IE> wrote:

I'm not sure I follow. Neither was *size in your example? It's a MYFLT*, what different would swapping that out for a 2 make? As in:

tabensure(csound, p->outArr, 2);

Or perhaps I misunderstood your origin question?



On 3 January 2016 at 15:23, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.



Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>




Date2016-01-03 19:33
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
So I'm now trying to populate my array output with strings when the opcode starts. It works fine until Csound stops, at which point I get a segfault. Perhaps I'm not setting the correct size for each string?

static int testopcode(CSOUND *csound, TEST_STRUCT* p)
{
   int  i;
   tabensure(csound, p->outArr, *p->size);
   STRINGDAT *strings = (STRINGDAT *) p->outArr->data;


  /* this might not be necessary but it shows what STRINGDATS
     are made of  */
   for(i=0; i < *p->size; i++){
          strings[i].size = strlen("test")*sizeof(char*);
          strings[i].data = "test";
   }
   return OK;
}

My instrument now looks like this:

Sarr[] testopcode 2
prints Sarr[0]
prints Sarr[1]


On 3 January 2016 at 16:20, Rory Walsh <rorywalsh@ear.ie> wrote:
Ok, I see now where the confusion is coming from. I didn't pass 2 as the array size in my opcode. I simply passed a 2 as the size parameter to the tabensure() function as in my previously quoted code.

On 3 January 2016 at 16:07, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
the S type would not match 2 as a parameter to the opcode and csound should have given a syntax error

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 16:03, Rory Walsh <rorywalsh@EAR.IE> wrote:

I'm not sure I follow. Neither was *size in your example? It's a MYFLT*, what different would swapping that out for a 2 make? As in:

tabensure(csound, p->outArr, 2);

Or perhaps I misunderstood your origin question?



On 3 January 2016 at 15:23, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.



Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:

but with S, how do you pass the array size?

Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland

On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:

I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:

#define S(x)    sizeof(x)
static OENTRY localops[] = {
 { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
};
LINKAGE

Let me know if there is anything else you need me to try out.

On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
That’s strange. What happens if you replace testopcode with init?

If the testopcode is never called, then it cannot be a problem with this code.
========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>
> On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
> The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>
> On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
> Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>
> ==3693== Memcheck, a memory error detector
> ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==3693== Command: csound ../Opcodes/directory.csd
> ==3693== Parent PID: 2340
> ==3693==
> ==3693== Invalid read of size 8
> ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
> ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
> ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
> ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
> ==3693==    by 0x4FF44CE: reset (csound.c:2961)
> ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
> ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
> ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>
> On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
> Or if you can run in a debugger, can you check it there?
>
> Did you try running this under the csound command? That’s how I am testing here.
>
> ========================
> Dr Victor Lazzarini
> Dean of Arts, Celtic Studies and Philosophy,
> Maynooth University,
> Maynooth, Co Kildare, Ireland
> Tel: 00 353 7086936
> Fax: 00 353 1 7086952
>
> > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
> >
> > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
> >
> > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
> > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
> >
> > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > yes. I checked under the debugger, there does not seem to be any problem. The code looks
> > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
> > ========================
> > Dr Victor Lazzarini
> > Dean of Arts, Celtic Studies and Philosophy,
> > Maynooth University,
> > Maynooth, Co Kildare, Ireland
> > Tel: 00 353 7086936
> > Fax: 00 353 1 7086952
> >
> > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >
> > > Perhaps a platform issue? I take it you're on OSX?
> > >
> > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > > I don't know, it works here. I will have a look.
> > >
> > > Victor Lazzarini
> > > Dean of Arts, Celtic Studies, and Philosophy
> > > Maynooth University
> > > Ireland
> > >
> > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >
> > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
> > >>
> > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
> > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
> > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
> > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
> > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
> > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
> > >> 6  0x00000000004017d1  main
> > >>
> > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
> > >> a little modification to my earlier code creates an array of empty strings:
> > >>
> > >> =========
> > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> {
> > >>    int  i;
> > >>    tabensure(csound, p->outArr,*p->size);
> > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> > >>
> > >>   /* this might not be necessary but it shows what STRINGDATS
> > >>      are made of  */
> > >>    for(i=0; i < *p->size; i++){
> > >>           strings[i].size = 0;
> > >>           strings[i].data = NULL;
> > >>    }
> > >>    return OK;
> > >> }
> > >>
> > >> #define S(x)    sizeof(x)
> > >> static OENTRY localops[] = {
> > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> };
> > >> LINKAGE
> > >> ==========
> > >> test code:
> > >>
> > >>  instr 1
> > >> Sarr[] testopcode 2
> > >> Sarr[0] = "test\n"
> > >> Sarr[1] = "now \n"
> > >> prints Sarr[0]
> > >> prints Sarr[1]
> > >> endin
> > >>
> > >> =========
> > >>
> > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
> > >> than I made it look.
> > >>
> > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
> > >> CSOUND structure, as it looks to be useful in a generic way.
> > >>
> > >> ========================
> > >> Dr Victor Lazzarini
> > >> Dean of Arts, Celtic Studies and Philosophy,
> > >> Maynooth University,
> > >> Maynooth, Co Kildare, Ireland
> > >> Tel: 00 353 7086936
> > >> Fax: 00 353 1 7086952
> > >>
> > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> >
> > >> > Thanks Victor. I'll keep at it.
> > >> >
> > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > No comments means you should read the code not the comments. It’s deliberate.
> > >> > I’ll try to put together an example.
> > >> >
> > >> > Victor
> > >> > ========================
> > >> > Dr Victor Lazzarini
> > >> > Dean of Arts, Celtic Studies and Philosophy,
> > >> > Maynooth University,
> > >> > Maynooth, Co Kildare, Ireland
> > >> > Tel: 00 353 7086936
> > >> > Fax: 00 353 1 7086952
> > >> >
> > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >
> > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
> > >> > >
> > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > > If you are creating the array, you will need to
> > >> > > allocate memory for stringdat structs and
> > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
> > >> > >
> > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
> > >> > > to understand how the typesystem works.
> > >> > > I don't think there is a quick guide to doing
> > >> > > this at the moment.
> > >> > >
> > >> > > We might think of introducing an API for
> > >> > > advanced data types so that opcode
> > >> > > developers can do this more safely.
> > >> > >
> > >> > > Victor Lazzarini
> > >> > > Dean of Arts, Celtic Studies, and Philosophy
> > >> > > Maynooth University
> > >> > > Ireland
> > >> > >
> > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >
> > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
> > >> > >> it).
> > >> > >>
> > >> > >> Victor Lazzarini
> > >> > >> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >> Maynooth University
> > >> > >> Ireland
> > >> > >>
> > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>
> > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
> > >> > >>>
> > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
> > >> > >>>
> > >> > >>> Don't worry about memory management, Csound takes care of it.
> > >> > >>>
> > >> > >>> Victor Lazzarini
> > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
> > >> > >>> Maynooth University
> > >> > >>> Ireland
> > >> > >>>
> > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
> > >> > >>>
> > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
> > >> > >>>>
> > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
> > >> > >>>> Found: i[] testopcode i
> > >> > >>>> Line: 9
> > >> > >>>>
> > >> > >>>> Yet localops[] looks like this?
> > >> > >>>>
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>>
> > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
> > >> > >>>>
> > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> > >> > >>>> Here it goes.
> > >> > >>>> arrays.c is your friend.
> > >> > >>>> ===========================================================
> > >> > >>>> #include <csdl.h>
> > >> > >>>>
> > >> > >>>> typedef struct {
> > >> > >>>>   OPDS    h;
> > >> > >>>>   ARRAYDAT* outArr;
> > >> > >>>>   MYFLT *size;
> > >> > >>>> } TEST_STRUCT;
> > >> > >>>>
> > >> > >>>> /* from opcodes/arrays.c */
> > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
> > >> > >>>> {
> > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
> > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
> > >> > >>>>       size_t ss;
> > >> > >>>>       if (p->data == NULL) {
> > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
> > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
> > >> > >>>>       }
> > >> > >>>>
> > >> > >>>>       ss = p->arrayMemberSize*size;
> > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
> > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
> > >> > >>>>       p->dimensions = 1;
> > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
> > >> > >>>>       p->sizes[0] = size;
> > >> > >>>>   }
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> {
> > >> > >>>>     int  i;
> > >> > >>>>     tabensure(csound, p->outArr,*p->size);
> > >> > >>>>     for(i=0; i < *p->size; i++)
> > >> > >>>>        p->outArr->data[i] = i;
> > >> > >>>>     return OK;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> #define S(x)    sizeof(x)
> > >> > >>>> static OENTRY localops[] = {
> > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> };
> > >> > >>>> LINKAGE
> > >> > >>>>
> > >> > >>>>
> > >> > >>>> ========================
> > >> > >>>> Dr Victor Lazzarini
> > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
> > >> > >>>> Maynooth University,
> > >> > >>>> Maynooth, Co Kildare, Ireland
> > >> > >>>> Tel: 00 353 7086936
> > >> > >>>> Fax: 00 353 1 7086952
> > >> > >>>>
> > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
> > >> > >>>> >
> > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
> > >> > >>>> >
> > >> > >>>> > i1[] testopcode 10
> > >> > >>>> >
> > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
> > >> > >>>> >
> > >> > >>>> > #include <csdl.h>
> > >> > >>>> >
> > >> > >>>> > typedef struct {
> > >> > >>>> >   OPDS    h;
> > >> > >>>> >   ARRAYDAT* outArr;
> > >> > >>>> > } TEST_STRUCT;
> > >> > >>>> >
> > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> > >> > >>>> > {
> > >> > >>>> >     return OK;
> > >> > >>>> > }
> > >> > >>>> >
> > >> > >>>> > #define S(x)    sizeof(x)
> > >> > >>>> > static OENTRY localops[] = {
> > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
> > >> > >>>> > };
> > >> > >>>> > LINKAGE
> > >> > >>>>
> > >> > >>>
> > >> > >
> > >> >
> > >>
> > >
> >
> >
>
>
>





Date2016-01-03 19:47
FromVictor Lazzarini
SubjectRe: [Csnd-dev] opcodes that output arrays..
You should not use string constants, that will give you trouble. Allocate memory for them, and
then copy them in. 

strings[i]->data = csound->Strdup(csound, string) 

will do both things.


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952 

> On 3 Jan 2016, at 19:33, Rory Walsh  wrote:
> 
> So I'm now trying to populate my array output with strings when the opcode starts. It works fine until Csound stops, at which point I get a segfault. Perhaps I'm not setting the correct size for each string? 
> 
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>    int  i;
>    tabensure(csound, p->outArr, *p->size);
>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
> 
> 
>   /* this might not be necessary but it shows what STRINGDATS
>      are made of  */
>    for(i=0; i < *p->size; i++){
>           strings[i].size = strlen("test")*sizeof(char*);
>           strings[i].data = "test";
>    }
>    return OK;
> }
> 
> My instrument now looks like this:
> 
> Sarr[] testopcode 2
> prints Sarr[0]
> prints Sarr[1]
> 
> 
> On 3 January 2016 at 16:20, Rory Walsh  wrote:
> Ok, I see now where the confusion is coming from. I didn't pass 2 as the array size in my opcode. I simply passed a 2 as the size parameter to the tabensure() function as in my previously quoted code. 
> 
> On 3 January 2016 at 16:07, Victor Lazzarini  wrote:
> the S type would not match 2 as a parameter to the opcode and csound should have given a syntax error
> 
> Victor Lazzarini
> Dean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland
> 
> On 3 Jan 2016, at 16:03, Rory Walsh  wrote:
> 
>> I'm not sure I follow. Neither was *size in your example? It's a MYFLT*, what different would swapping that out for a 2 make? As in:
>> 
>> tabensure(csound, p->outArr, 2);
>> 
>> Or perhaps I misunderstood your origin question?
>> 
>> 
>> 
>> On 3 January 2016 at 15:23, Victor Lazzarini  wrote:
>> yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.
>> 
>> 
>> 
>> Victor Lazzarini
>> Dean of Arts, Celtic Studies, and Philosophy
>> Maynooth University
>> Ireland
>> 
>> On 3 Jan 2016, at 14:45, Victor Lazzarini  wrote:
>> 
>>> but with S, how do you pass the array size?
>>> 
>>> Victor Lazzarini
>>> Dean of Arts, Celtic Studies, and Philosophy
>>> Maynooth University
>>> Ireland
>>> 
>>> On 3 Jan 2016, at 14:38, Rory Walsh  wrote:
>>> 
>>>> I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:
>>>> 
>>>> #define S(x)    sizeof(x)
>>>> static OENTRY localops[] = {
>>>>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
>>>> };
>>>> LINKAGE
>>>> 
>>>> Let me know if there is anything else you need me to try out.
>>>> 
>>>> On 3 January 2016 at 13:59, Victor Lazzarini  wrote:
>>>> That’s strange. What happens if you replace testopcode with init?
>>>> 
>>>> If the testopcode is never called, then it cannot be a problem with this code.
>>>> ========================
>>>> Dr Victor Lazzarini
>>>> Dean of Arts, Celtic Studies and Philosophy,
>>>> Maynooth University,
>>>> Maynooth, Co Kildare, Ireland
>>>> Tel: 00 353 7086936
>>>> Fax: 00 353 1 7086952
>>>> 
>>>> > On 3 Jan 2016, at 13:45, Rory Walsh  wrote:
>>>> >
>>>> > I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>>>> >
>>>> > On 3 January 2016 at 13:37, Rory Walsh  wrote:
>>>> > The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>>>> >
>>>> > On 3 January 2016 at 13:34, Rory Walsh  wrote:
>>>> > Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>>>> >
>>>> > ==3693== Memcheck, a memory error detector
>>>> > ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
>>>> > ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
>>>> > ==3693== Command: csound ../Opcodes/directory.csd
>>>> > ==3693== Parent PID: 2340
>>>> > ==3693==
>>>> > ==3693== Invalid read of size 8
>>>> > ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
>>>> > ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
>>>> > ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
>>>> > ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
>>>> > ==3693==    by 0x4FF44CE: reset (csound.c:2961)
>>>> > ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
>>>> > ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
>>>> > ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>>>> >
>>>> > On 3 January 2016 at 13:30, Victor Lazzarini  wrote:
>>>> > Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
>>>> > Or if you can run in a debugger, can you check it there?
>>>> >
>>>> > Did you try running this under the csound command? That’s how I am testing here.
>>>> >
>>>> > ========================
>>>> > Dr Victor Lazzarini
>>>> > Dean of Arts, Celtic Studies and Philosophy,
>>>> > Maynooth University,
>>>> > Maynooth, Co Kildare, Ireland
>>>> > Tel: 00 353 7086936
>>>> > Fax: 00 353 1 7086952
>>>> >
>>>> > > On 3 Jan 2016, at 13:14, Rory Walsh  wrote:
>>>> > >
>>>> > > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
>>>> > >
>>>> > > On 3 January 2016 at 13:06, Rory Walsh  wrote:
>>>> > > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
>>>> > >
>>>> > > On 3 January 2016 at 12:47, Victor Lazzarini  wrote:
>>>> > > yes. I checked under the debugger, there does not seem to be any problem. The code looks
>>>> > > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
>>>> > > ========================
>>>> > > Dr Victor Lazzarini
>>>> > > Dean of Arts, Celtic Studies and Philosophy,
>>>> > > Maynooth University,
>>>> > > Maynooth, Co Kildare, Ireland
>>>> > > Tel: 00 353 7086936
>>>> > > Fax: 00 353 1 7086952
>>>> > >
>>>> > > > On 3 Jan 2016, at 12:09, Rory Walsh  wrote:
>>>> > > >
>>>> > > > Perhaps a platform issue? I take it you're on OSX?
>>>> > > >
>>>> > > > On 3 January 2016 at 12:06, Victor Lazzarini  wrote:
>>>> > > > I don't know, it works here. I will have a look.
>>>> > > >
>>>> > > > Victor Lazzarini
>>>> > > > Dean of Arts, Celtic Studies, and Philosophy
>>>> > > > Maynooth University
>>>> > > > Ireland
>>>> > > >
>>>> > > > On 3 Jan 2016, at 10:10, Rory Walsh  wrote:
>>>> > > >
>>>> > > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
>>>> > > >>
>>>> > > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
>>>> > > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
>>>> > > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
>>>> > > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
>>>> > > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
>>>> > > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
>>>> > > >> 6  0x00000000004017d1  main
>>>> > > >>
>>>> > > >> On 2 January 2016 at 18:20, Victor Lazzarini  wrote:
>>>> > > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
>>>> > > >> a little modification to my earlier code creates an array of empty strings:
>>>> > > >>
>>>> > > >> =========
>>>> > > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> > > >> {
>>>> > > >>    int  i;
>>>> > > >>    tabensure(csound, p->outArr,*p->size);
>>>> > > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
>>>> > > >>
>>>> > > >>   /* this might not be necessary but it shows what STRINGDATS
>>>> > > >>      are made of  */
>>>> > > >>    for(i=0; i < *p->size; i++){
>>>> > > >>           strings[i].size = 0;
>>>> > > >>           strings[i].data = NULL;
>>>> > > >>    }
>>>> > > >>    return OK;
>>>> > > >> }
>>>> > > >>
>>>> > > >> #define S(x)    sizeof(x)
>>>> > > >> static OENTRY localops[] = {
>>>> > > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
>>>> > > >> };
>>>> > > >> LINKAGE
>>>> > > >> ==========
>>>> > > >> test code:
>>>> > > >>
>>>> > > >>  instr 1
>>>> > > >> Sarr[] testopcode 2
>>>> > > >> Sarr[0] = "test\n"
>>>> > > >> Sarr[1] = "now \n"
>>>> > > >> prints Sarr[0]
>>>> > > >> prints Sarr[1]
>>>> > > >> endin
>>>> > > >>
>>>> > > >> =========
>>>> > > >>
>>>> > > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
>>>> > > >> than I made it look.
>>>> > > >>
>>>> > > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
>>>> > > >> CSOUND structure, as it looks to be useful in a generic way.
>>>> > > >>
>>>> > > >> ========================
>>>> > > >> Dr Victor Lazzarini
>>>> > > >> Dean of Arts, Celtic Studies and Philosophy,
>>>> > > >> Maynooth University,
>>>> > > >> Maynooth, Co Kildare, Ireland
>>>> > > >> Tel: 00 353 7086936
>>>> > > >> Fax: 00 353 1 7086952
>>>> > > >>
>>>> > > >> > On 2 Jan 2016, at 13:08, Rory Walsh  wrote:
>>>> > > >> >
>>>> > > >> > Thanks Victor. I'll keep at it.
>>>> > > >> >
>>>> > > >> > On 2 January 2016 at 12:56, Victor Lazzarini  wrote:
>>>> > > >> > No comments means you should read the code not the comments. It’s deliberate.
>>>> > > >> > I’ll try to put together an example.
>>>> > > >> >
>>>> > > >> > Victor
>>>> > > >> > ========================
>>>> > > >> > Dr Victor Lazzarini
>>>> > > >> > Dean of Arts, Celtic Studies and Philosophy,
>>>> > > >> > Maynooth University,
>>>> > > >> > Maynooth, Co Kildare, Ireland
>>>> > > >> > Tel: 00 353 7086936
>>>> > > >> > Fax: 00 353 1 7086952
>>>> > > >> >
>>>> > > >> > > On 2 Jan 2016, at 12:47, Rory Walsh  wrote:
>>>> > > >> > >
>>>> > > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
>>>> > > >> > >
>>>> > > >> > > On 2 January 2016 at 12:31, Victor Lazzarini  wrote:
>>>> > > >> > > If you are creating the array, you will need to
>>>> > > >> > > allocate memory for stringdat structs and
>>>> > > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
>>>> > > >> > >
>>>> > > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
>>>> > > >> > > to understand how the typesystem works.
>>>> > > >> > > I don't think there is a quick guide to doing
>>>> > > >> > > this at the moment.
>>>> > > >> > >
>>>> > > >> > > We might think of introducing an API for
>>>> > > >> > > advanced data types so that opcode
>>>> > > >> > > developers can do this more safely.
>>>> > > >> > >
>>>> > > >> > > Victor Lazzarini
>>>> > > >> > > Dean of Arts, Celtic Studies, and Philosophy
>>>> > > >> > > Maynooth University
>>>> > > >> > > Ireland
>>>> > > >> > >
>>>> > > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini  wrote:
>>>> > > >> > >
>>>> > > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
>>>> > > >> > >> it).
>>>> > > >> > >>
>>>> > > >> > >> Victor Lazzarini
>>>> > > >> > >> Dean of Arts, Celtic Studies, and Philosophy
>>>> > > >> > >> Maynooth University
>>>> > > >> > >> Ireland
>>>> > > >> > >>
>>>> > > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh  wrote:
>>>> > > >> > >>
>>>> > > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
>>>> > > >> > >>>
>>>> > > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini  wrote:
>>>> > > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
>>>> > > >> > >>>
>>>> > > >> > >>> Don't worry about memory management, Csound takes care of it.
>>>> > > >> > >>>
>>>> > > >> > >>> Victor Lazzarini
>>>> > > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
>>>> > > >> > >>> Maynooth University
>>>> > > >> > >>> Ireland
>>>> > > >> > >>>
>>>> > > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh  wrote:
>>>> > > >> > >>>
>>>> > > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
>>>> > > >> > >>>>
>>>> > > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
>>>> > > >> > >>>> Found: i[] testopcode i
>>>> > > >> > >>>> Line: 9
>>>> > > >> > >>>>
>>>> > > >> > >>>> Yet localops[] looks like this?
>>>> > > >> > >>>>
>>>> > > >> > >>>> static OENTRY localops[] = {
>>>> > > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
>>>> > > >> > >>>> };
>>>> > > >> > >>>>
>>>> > > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
>>>> > > >> > >>>>
>>>> > > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini  wrote:
>>>> > > >> > >>>> Here it goes.
>>>> > > >> > >>>> arrays.c is your friend.
>>>> > > >> > >>>> ===========================================================
>>>> > > >> > >>>> #include 
>>>> > > >> > >>>>
>>>> > > >> > >>>> typedef struct {
>>>> > > >> > >>>>   OPDS    h;
>>>> > > >> > >>>>   ARRAYDAT* outArr;
>>>> > > >> > >>>>   MYFLT *size;
>>>> > > >> > >>>> } TEST_STRUCT;
>>>> > > >> > >>>>
>>>> > > >> > >>>> /* from opcodes/arrays.c */
>>>> > > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
>>>> > > >> > >>>> {
>>>> > > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
>>>> > > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
>>>> > > >> > >>>>       size_t ss;
>>>> > > >> > >>>>       if (p->data == NULL) {
>>>> > > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
>>>> > > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
>>>> > > >> > >>>>       }
>>>> > > >> > >>>>
>>>> > > >> > >>>>       ss = p->arrayMemberSize*size;
>>>> > > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>>>> > > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
>>>> > > >> > >>>>       p->dimensions = 1;
>>>> > > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
>>>> > > >> > >>>>       p->sizes[0] = size;
>>>> > > >> > >>>>   }
>>>> > > >> > >>>> }
>>>> > > >> > >>>>
>>>> > > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> > > >> > >>>> {
>>>> > > >> > >>>>     int  i;
>>>> > > >> > >>>>     tabensure(csound, p->outArr,*p->size);
>>>> > > >> > >>>>     for(i=0; i < *p->size; i++)
>>>> > > >> > >>>>        p->outArr->data[i] = i;
>>>> > > >> > >>>>     return OK;
>>>> > > >> > >>>> }
>>>> > > >> > >>>>
>>>> > > >> > >>>> #define S(x)    sizeof(x)
>>>> > > >> > >>>> static OENTRY localops[] = {
>>>> > > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
>>>> > > >> > >>>> };
>>>> > > >> > >>>> LINKAGE
>>>> > > >> > >>>>
>>>> > > >> > >>>>
>>>> > > >> > >>>> ========================
>>>> > > >> > >>>> Dr Victor Lazzarini
>>>> > > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
>>>> > > >> > >>>> Maynooth University,
>>>> > > >> > >>>> Maynooth, Co Kildare, Ireland
>>>> > > >> > >>>> Tel: 00 353 7086936
>>>> > > >> > >>>> Fax: 00 353 1 7086952
>>>> > > >> > >>>>
>>>> > > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh  wrote:
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > i1[] testopcode 10
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > #include 
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > typedef struct {
>>>> > > >> > >>>> >   OPDS    h;
>>>> > > >> > >>>> >   ARRAYDAT* outArr;
>>>> > > >> > >>>> > } TEST_STRUCT;
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> > > >> > >>>> > {
>>>> > > >> > >>>> >     return OK;
>>>> > > >> > >>>> > }
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > #define S(x)    sizeof(x)
>>>> > > >> > >>>> > static OENTRY localops[] = {
>>>> > > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
>>>> > > >> > >>>> > };
>>>> > > >> > >>>> > LINKAGE
>>>> > > >> > >>>>
>>>> > > >> > >>>
>>>> > > >> > >
>>>> > > >> >
>>>> > > >>
>>>> > > >
>>>> > >
>>>> > >
>>>> >
>>>> >
>>>> >
>>>> 
>> 
> 

Date2016-01-03 20:24
FromRory Walsh
SubjectRe: [Csnd-dev] opcodes that output arrays..
Thanks Victor. That works nicely. No problems on exit now.

On 3 January 2016 at 19:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
You should not use string constants, that will give you trouble. Allocate memory for them, and
then copy them in.

strings[i]->data = csound->Strdup(csound, string)

will do both things.


========================
Dr Victor Lazzarini
Dean of Arts, Celtic Studies and Philosophy,
Maynooth University,
Maynooth, Co Kildare, Ireland
Tel: 00 353 7086936
Fax: 00 353 1 7086952

> On 3 Jan 2016, at 19:33, Rory Walsh <rorywalsh@ear.ie> wrote:
>
> So I'm now trying to populate my array output with strings when the opcode starts. It works fine until Csound stops, at which point I get a segfault. Perhaps I'm not setting the correct size for each string?
>
> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
> {
>    int  i;
>    tabensure(csound, p->outArr, *p->size);
>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
>
>
>   /* this might not be necessary but it shows what STRINGDATS
>      are made of  */
>    for(i=0; i < *p->size; i++){
>           strings[i].size = strlen("test")*sizeof(char*);
>           strings[i].data = "test";
>    }
>    return OK;
> }
>
> My instrument now looks like this:
>
> Sarr[] testopcode 2
> prints Sarr[0]
> prints Sarr[1]
>
>
> On 3 January 2016 at 16:20, Rory Walsh <rorywalsh@ear.ie> wrote:
> Ok, I see now where the confusion is coming from. I didn't pass 2 as the array size in my opcode. I simply passed a 2 as the size parameter to the tabensure() function as in my previously quoted code.
>
> On 3 January 2016 at 16:07, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
> the S type would not match 2 as a parameter to the opcode and csound should have given a syntax error
>
> Victor Lazzarini
> Dean of Arts, Celtic Studies, and Philosophy
> Maynooth University
> Ireland
>
> On 3 Jan 2016, at 16:03, Rory Walsh <rorywalsh@EAR.IE> wrote:
>
>> I'm not sure I follow. Neither was *size in your example? It's a MYFLT*, what different would swapping that out for a 2 make? As in:
>>
>> tabensure(csound, p->outArr, 2);
>>
>> Or perhaps I misunderstood your origin question?
>>
>>
>>
>> On 3 January 2016 at 15:23, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>> yes, but 2 is not a string! So it does not match S as the type, and it should not compile. I think there is something else wrong in your system.
>>
>>
>>
>> Victor Lazzarini
>> Dean of Arts, Celtic Studies, and Philosophy
>> Maynooth University
>> Ireland
>>
>> On 3 Jan 2016, at 14:45, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>
>>> but with S, how do you pass the array size?
>>>
>>> Victor Lazzarini
>>> Dean of Arts, Celtic Studies, and Philosophy
>>> Maynooth University
>>> Ireland
>>>
>>> On 3 Jan 2016, at 14:38, Rory Walsh <rorywalsh@EAR.IE> wrote:
>>>
>>>> I already tried that, init works fine. Is seems that as soon as I use S[] as the output type in the OENTRY struct for a plugin opcode I get this problem. But oddly enough, if I use S as the input type along with that I get no problem. So the following for example works fine:
>>>>
>>>> #define S(x)    sizeof(x)
>>>> static OENTRY localops[] = {
>>>>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "S", (SUBR)testopcode, NULL, NULL   },
>>>> };
>>>> LINKAGE
>>>>
>>>> Let me know if there is anything else you need me to try out.
>>>>
>>>> On 3 January 2016 at 13:59, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> That’s strange. What happens if you replace testopcode with init?
>>>>
>>>> If the testopcode is never called, then it cannot be a problem with this code.
>>>> ========================
>>>> Dr Victor Lazzarini
>>>> Dean of Arts, Celtic Studies and Philosophy,
>>>> Maynooth University,
>>>> Maynooth, Co Kildare, Ireland
>>>> Tel: 00 353 7086936
>>>> Fax: 00 353 1 7086952
>>>>
>>>> > On 3 Jan 2016, at 13:45, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> >
>>>> > I can step through to until csoundStart(csound); is called in csoundCompile(). At this point I get a segfault and the debugger provides me with the same backtrace I posted earlier.
>>>> >
>>>> > On 3 January 2016 at 13:37, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> > The opcodetest function never gets hit. I'm stepping through now from OENTRY localops[]..
>>>> >
>>>> > On 3 January 2016 at 13:34, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> > Yeah, I'm only testing with csound, not a frontend. I'll try your suggestion now. In the meantime, here is the Csound bit of the output from valigrind in case that helps.
>>>> >
>>>> > ==3693== Memcheck, a memory error detector
>>>> > ==3693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
>>>> > ==3693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
>>>> > ==3693== Command: csound ../Opcodes/directory.csd
>>>> > ==3693== Parent PID: 2340
>>>> > ==3693==
>>>> > ==3693== Invalid read of size 8
>>>> > ==3693==    at 0x4EA9CBB: string_free_var_mem (csound_standard_types.c:251)
>>>> > ==3693==    by 0x4E8C945: free_instr_var_memory (insert.c:854)
>>>> > ==3693==    by 0x4E8CA7A: orcompact (insert.c:882)
>>>> > ==3693==    by 0x4E986E4: csoundCleanup (musmon.c:455)
>>>> > ==3693==    by 0x4FF44CE: reset (csound.c:2961)
>>>> > ==3693==    by 0x4FF02A4: csoundDestroy (csound.c:1241)
>>>> > ==3693==    by 0x4017D0: main (in /usr/local/bin/csound)
>>>> > ==3693==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
>>>> >
>>>> > On 3 January 2016 at 13:30, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > Interesting. Can you place a printf() in tabensure() to print these pointers to see if they are non-NULL?
>>>> > Or if you can run in a debugger, can you check it there?
>>>> >
>>>> > Did you try running this under the csound command? That’s how I am testing here.
>>>> >
>>>> > ========================
>>>> > Dr Victor Lazzarini
>>>> > Dean of Arts, Celtic Studies and Philosophy,
>>>> > Maynooth University,
>>>> > Maynooth, Co Kildare, Ireland
>>>> > Tel: 00 353 7086936
>>>> > Fax: 00 353 1 7086952
>>>> >
>>>> > > On 3 Jan 2016, at 13:14, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> > >
>>>> > > I get a segfault if I try to access either *sizes or *data. The other members seem fine from what I can tell.
>>>> > >
>>>> > > On 3 January 2016 at 13:06, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> > > It wouldn't have anything to do with how I'm building/using the opcode? I'm just adding a make_plugin() to Opcodes/CMakeLists.txt, and running make/install. I'm stepping through the debugger here at array_free_var_mem(). It crashes as soon as it tests dat->data. In fact, any operations at all on that member causes a segmentation fault.
>>>> > >
>>>> > > On 3 January 2016 at 12:47, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > > yes. I checked under the debugger, there does not seem to be any problem. The code looks
>>>> > > correct, the correct amount of memory is allocated. The crash seems by your description at the freeing stage.
>>>> > > ========================
>>>> > > Dr Victor Lazzarini
>>>> > > Dean of Arts, Celtic Studies and Philosophy,
>>>> > > Maynooth University,
>>>> > > Maynooth, Co Kildare, Ireland
>>>> > > Tel: 00 353 7086936
>>>> > > Fax: 00 353 1 7086952
>>>> > >
>>>> > > > On 3 Jan 2016, at 12:09, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> > > >
>>>> > > > Perhaps a platform issue? I take it you're on OSX?
>>>> > > >
>>>> > > > On 3 January 2016 at 12:06, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > > > I don't know, it works here. I will have a look.
>>>> > > >
>>>> > > > Victor Lazzarini
>>>> > > > Dean of Arts, Celtic Studies, and Philosophy
>>>> > > > Maynooth University
>>>> > > > Ireland
>>>> > > >
>>>> > > > On 3 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
>>>> > > >
>>>> > > >> Hi Victor. This looks a lot easier but I get a crash when running it. Here's the backtrace:
>>>> > > >>
>>>> > > >> 0  0x00007ffff790fd0e  array_free_var_mem  /home/rory/sourcecode/cabbageaudio/csound/Engine/csound_standard_types.c  260
>>>> > > >> 1  0x00007ffff78f2946  free_instr_var_memory  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  854
>>>> > > >> 2  0x00007ffff78f2a7b  orcompact  /home/rory/sourcecode/cabbageaudio/csound/Engine/insert.c  882
>>>> > > >> 3  0x00007ffff78fe6e5  csoundCleanup  /home/rory/sourcecode/cabbageaudio/csound/Engine/musmon.c  455
>>>> > > >> 4  0x00007ffff7a5a624  reset  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  2961
>>>> > > >> 5  0x00007ffff7a563fa  csoundDestroy  /home/rory/sourcecode/cabbageaudio/csound/Top/csound.c  1241
>>>> > > >> 6  0x00000000004017d1  main
>>>> > > >>
>>>> > > >> On 2 January 2016 at 18:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > > >> Actually, I was wrong, tabensure() is generic and will create any array type for you, so
>>>> > > >> a little modification to my earlier code creates an array of empty strings:
>>>> > > >>
>>>> > > >> =========
>>>> > > >> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> > > >> {
>>>> > > >>    int  i;
>>>> > > >>    tabensure(csound, p->outArr,*p->size);
>>>> > > >>    STRINGDAT *strings = (STRINGDAT *) p->outArr->data;
>>>> > > >>
>>>> > > >>   /* this might not be necessary but it shows what STRINGDATS
>>>> > > >>      are made of  */
>>>> > > >>    for(i=0; i < *p->size; i++){
>>>> > > >>           strings[i].size = 0;
>>>> > > >>           strings[i].data = NULL;
>>>> > > >>    }
>>>> > > >>    return OK;
>>>> > > >> }
>>>> > > >>
>>>> > > >> #define S(x)    sizeof(x)
>>>> > > >> static OENTRY localops[] = {
>>>> > > >>  { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i", (SUBR)testopcode, NULL, NULL   },
>>>> > > >> };
>>>> > > >> LINKAGE
>>>> > > >> ==========
>>>> > > >> test code:
>>>> > > >>
>>>> > > >>  instr 1
>>>> > > >> Sarr[] testopcode 2
>>>> > > >> Sarr[0] = "test\n"
>>>> > > >> Sarr[1] = "now \n"
>>>> > > >> prints Sarr[0]
>>>> > > >> prints Sarr[1]
>>>> > > >> endin
>>>> > > >>
>>>> > > >> =========
>>>> > > >>
>>>> > > >> Sorry about the misleading replies, I was not taking the time to look at the code. It’s simpler
>>>> > > >> than I made it look.
>>>> > > >>
>>>> > > >> Maybe we should think of moving tabensure() out of arrays.c and exposing it through the
>>>> > > >> CSOUND structure, as it looks to be useful in a generic way.
>>>> > > >>
>>>> > > >> ========================
>>>> > > >> Dr Victor Lazzarini
>>>> > > >> Dean of Arts, Celtic Studies and Philosophy,
>>>> > > >> Maynooth University,
>>>> > > >> Maynooth, Co Kildare, Ireland
>>>> > > >> Tel: 00 353 7086936
>>>> > > >> Fax: 00 353 1 7086952
>>>> > > >>
>>>> > > >> > On 2 Jan 2016, at 13:08, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> > > >> >
>>>> > > >> > Thanks Victor. I'll keep at it.
>>>> > > >> >
>>>> > > >> > On 2 January 2016 at 12:56, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > > >> > No comments means you should read the code not the comments. It’s deliberate.
>>>> > > >> > I’ll try to put together an example.
>>>> > > >> >
>>>> > > >> > Victor
>>>> > > >> > ========================
>>>> > > >> > Dr Victor Lazzarini
>>>> > > >> > Dean of Arts, Celtic Studies and Philosophy,
>>>> > > >> > Maynooth University,
>>>> > > >> > Maynooth, Co Kildare, Ireland
>>>> > > >> > Tel: 00 353 7086936
>>>> > > >> > Fax: 00 353 1 7086952
>>>> > > >> >
>>>> > > >> > > On 2 Jan 2016, at 12:47, Rory Walsh <rorywalsh@EAR.IE> wrote:
>>>> > > >> > >
>>>> > > >> > > Thanks Victor. I think I may wait until such an API is developed. Looking through the source code is frightening. No a comment to be found! On top of that, I can't think of a single existing opcode that outputs a string array. No worries. Thanks for the help.
>>>> > > >> > >
>>>> > > >> > > On 2 January 2016 at 12:31, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > > >> > > If you are creating the array, you will need to
>>>> > > >> > > allocate memory for stringdat structs and
>>>> > > >> > > the memory for each string that us held by them. CS_TYPE needs also to be set.
>>>> > > >> > >
>>>> > > >> > > I am afraid you might need to look into arrays.c, and the other files under Engine/
>>>> > > >> > > to understand how the typesystem works.
>>>> > > >> > > I don't think there is a quick guide to doing
>>>> > > >> > > this at the moment.
>>>> > > >> > >
>>>> > > >> > > We might think of introducing an API for
>>>> > > >> > > advanced data types so that opcode
>>>> > > >> > > developers can do this more safely.
>>>> > > >> > >
>>>> > > >> > > Victor Lazzarini
>>>> > > >> > > Dean of Arts, Celtic Studies, and Philosophy
>>>> > > >> > > Maynooth University
>>>> > > >> > > Ireland
>>>> > > >> > >
>>>> > > >> > > On 2 Jan 2016, at 12:20, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > > >> > >
>>>> > > >> > >> String arrays will have STRINGDAT elements instead of MYFLT (cast the data member to
>>>> > > >> > >> it).
>>>> > > >> > >>
>>>> > > >> > >> Victor Lazzarini
>>>> > > >> > >> Dean of Arts, Celtic Studies, and Philosophy
>>>> > > >> > >> Maynooth University
>>>> > > >> > >> Ireland
>>>> > > >> > >>
>>>> > > >> > >> On 2 Jan 2016, at 12:02, Rory Walsh <rorywalsh@EAR.IE> wrote:
>>>> > > >> > >>
>>>> > > >> > >>> I was running things form within an IDE, and make install wasn't called. I would have expect a "error: syntax error, unexpected T_IDENT, expecting T_OPCODE or T_FUNCTION or ',' however. Anyhow, working now. Which brings me to my next query. How do I work with string arrays? I see ARRAYDAT has a member function called CS_TYPE, I suspect this is something I need to set? I'll have a dig around the source.
>>>> > > >> > >>>
>>>> > > >> > >>> On 2 January 2016 at 11:16, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > > >> > >>> This could be because the plugin is not being loaded and the opcode is not found.
>>>> > > >> > >>>
>>>> > > >> > >>> Don't worry about memory management, Csound takes care of it.
>>>> > > >> > >>>
>>>> > > >> > >>> Victor Lazzarini
>>>> > > >> > >>> Dean of Arts, Celtic Studies, and Philosophy
>>>> > > >> > >>> Maynooth University
>>>> > > >> > >>> Ireland
>>>> > > >> > >>>
>>>> > > >> > >>> On 2 Jan 2016, at 10:10, Rory Walsh <rorywalsh@EAR.IE> wrote:
>>>> > > >> > >>>
>>>> > > >> > >>>> Thanks Victor. When I try to run this I get a syntax error in my Csound code? It's odd, I get a:
>>>> > > >> > >>>>
>>>> > > >> > >>>> error:  Unable to find opcode entry for 'testopcode' with matching argument types:
>>>> > > >> > >>>> Found: i[] testopcode i
>>>> > > >> > >>>> Line: 9
>>>> > > >> > >>>>
>>>> > > >> > >>>> Yet localops[] looks like this?
>>>> > > >> > >>>>
>>>> > > >> > >>>> static OENTRY localops[] = {
>>>> > > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      "i[]", "i", (SUBR)testopcode, NULL, NULL   },
>>>> > > >> > >>>> };
>>>> > > >> > >>>>
>>>> > > >> > >>>> Apart from that little issue, do I have to worry about freeing the memory allocated in tabensure() afterwards?
>>>> > > >> > >>>>
>>>> > > >> > >>>> On 1 January 2016 at 23:52, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
>>>> > > >> > >>>> Here it goes.
>>>> > > >> > >>>> arrays.c is your friend.
>>>> > > >> > >>>> ===========================================================
>>>> > > >> > >>>> #include <csdl.h>
>>>> > > >> > >>>>
>>>> > > >> > >>>> typedef struct {
>>>> > > >> > >>>>   OPDS    h;
>>>> > > >> > >>>>   ARRAYDAT* outArr;
>>>> > > >> > >>>>   MYFLT *size;
>>>> > > >> > >>>> } TEST_STRUCT;
>>>> > > >> > >>>>
>>>> > > >> > >>>> /* from opcodes/arrays.c */
>>>> > > >> > >>>> static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size)
>>>> > > >> > >>>> {
>>>> > > >> > >>>>     if (p->data==NULL || p->dimensions == 0 ||
>>>> > > >> > >>>>         (p->dimensions==1 && p->sizes[0] < size)) {
>>>> > > >> > >>>>       size_t ss;
>>>> > > >> > >>>>       if (p->data == NULL) {
>>>> > > >> > >>>>         CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL);
>>>> > > >> > >>>>         p->arrayMemberSize = var->memBlockSize;
>>>> > > >> > >>>>       }
>>>> > > >> > >>>>
>>>> > > >> > >>>>       ss = p->arrayMemberSize*size;
>>>> > > >> > >>>>       if (p->data==NULL) p->data = (MYFLT*)csound->Calloc(csound, ss);
>>>> > > >> > >>>>       else p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss);
>>>> > > >> > >>>>       p->dimensions = 1;
>>>> > > >> > >>>>       p->sizes = (int*)csound->Malloc(csound, sizeof(int));
>>>> > > >> > >>>>       p->sizes[0] = size;
>>>> > > >> > >>>>   }
>>>> > > >> > >>>> }
>>>> > > >> > >>>>
>>>> > > >> > >>>> static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> > > >> > >>>> {
>>>> > > >> > >>>>     int  i;
>>>> > > >> > >>>>     tabensure(csound, p->outArr,*p->size);
>>>> > > >> > >>>>     for(i=0; i < *p->size; i++)
>>>> > > >> > >>>>        p->outArr->data[i] = i;
>>>> > > >> > >>>>     return OK;
>>>> > > >> > >>>> }
>>>> > > >> > >>>>
>>>> > > >> > >>>> #define S(x)    sizeof(x)
>>>> > > >> > >>>> static OENTRY localops[] = {
>>>> > > >> > >>>>   { "testopcode",  S(TEST_STRUCT),   0, 1,      “i[]", “i", (SUBR)testopcode, NULL, NULL   },
>>>> > > >> > >>>> };
>>>> > > >> > >>>> LINKAGE
>>>> > > >> > >>>>
>>>> > > >> > >>>>
>>>> > > >> > >>>> ========================
>>>> > > >> > >>>> Dr Victor Lazzarini
>>>> > > >> > >>>> Dean of Arts, Celtic Studies and Philosophy,
>>>> > > >> > >>>> Maynooth University,
>>>> > > >> > >>>> Maynooth, Co Kildare, Ireland
>>>> > > >> > >>>> Tel: 00 353 7086936
>>>> > > >> > >>>> Fax: 00 353 1 7086952
>>>> > > >> > >>>>
>>>> > > >> > >>>> > On 1 Jan 2016, at 12:47, Rory Walsh <rorywalsh@ear.ie> wrote:
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > I wanted to learn more about how opcodes work with arrays. What I would like to do is write a simple i-time only opcode that returns an array when called, something really basic like
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > i1[] testopcode 10
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > which will return a i-rate variable with 10 values. But I can't seem to get my head around it from looking through the arrays.c code? Any help to get started would be great. Below is the basic skeleton of a test opcode.
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > #include <csdl.h>
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > typedef struct {
>>>> > > >> > >>>> >   OPDS    h;
>>>> > > >> > >>>> >   ARRAYDAT* outArr;
>>>> > > >> > >>>> > } TEST_STRUCT;
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > static int testopcode(CSOUND *csound, TEST_STRUCT* p)
>>>> > > >> > >>>> > {
>>>> > > >> > >>>> >     return OK;
>>>> > > >> > >>>> > }
>>>> > > >> > >>>> >
>>>> > > >> > >>>> > #define S(x)    sizeof(x)
>>>> > > >> > >>>> > static OENTRY localops[] = {
>>>> > > >> > >>>> >   { "testopcode",  S(TEST_STRUCT),   0, 1,      "S[]", "i",    NULL, (SUBR)testopcode, NULL, NULL   },
>>>> > > >> > >>>> > };
>>>> > > >> > >>>> > LINKAGE
>>>> > > >> > >>>>
>>>> > > >> > >>>
>>>> > > >> > >
>>>> > > >> >
>>>> > > >>
>>>> > > >
>>>> > >
>>>> > >
>>>> >
>>>> >
>>>> >
>>>>
>>
>
>