Problem with developing plugin opcodes

Dear Csounders!

I am trying to make a new plugin opcode by following steps described here The Csound FLOSS Manual but it doesn’t work for some reason. I’ve also tried this example GitHub - csound/opcode_sdk: Plugin Opcode SDK but with same amount of success.

I compile opsrc.c file with gcc -O2 -shared -o newopc.dll opsrc.c -DUSE_DOUBLE -I"C:\Program Files\Csound6_x64\include\csound". Generated .dll file is then in the same folder as my .csd file.
When I run csound .\13A01_newop.csd command I get this error:
error: syntax error, unexpected T_IDENT (token “newopc”) from file .\13A01_newop.csd (1)
line 11:
—asig newopc —
Unexpected untyped word asig when expecting a variable
Parsing failed due to invalid input!

I am working on windows 10 with this Csound version:
–Csound version 6.16 (double samples) Jul 17 2021
[commit: fb5bdb3681e15f56c216b4e4487b45848aa6b9f4]
libsndfile-1.0.31

Any ideas what I’m doing wrong?

Thank you.

I have also tried with copying newopc.dll manually to Csound6_x64\plugins64 folder but it also didn’t work.

I think there is some problem with loading .dll file but I’m not sure how to debug it :thinking:

I’ve figured it out. Problem was that I didn’t have LINKAGE at the end of the opsrc.c file.
If someone else stumbles upon same problem this is how opsrc.c should look like:

#include "csdl.h"

typedef struct  _newopc {
OPDS  h;
MYFLT *out;/* output pointer  */
MYFLT *in1,*in2,*in3; /* input pointers */
MYFLT  var1;  /* internal variables */
MYFLT  var2;
} newopc;

int newopc_init(CSOUND *csound, newopc *p){
    p->var1 = (MYFLT) 0;
    p->var2 = *p->in3;
    return OK;
}

int newopc_process_control(CSOUND *csound, newopc *p){
    MYFLT cnt = p->var1 + *(p->in2);
    if(cnt > p->var2) cnt = (MYFLT) 0; /* check bounds */
    *(p->out) = *(p->in1) + cnt; /* generate output */
    p->var1 = cnt; /* keep the value of cnt */
    return OK;
}

int newopc_process_audio(CSOUND *csound, newopc *p){
    int i, n = CS_KSMPS;
    MYFLT *aout = p->out;  /* output signal */
    MYFLT cnt = p->var1 + *(p->in2);
    uint32_t offset = p->h.insdshead->ksmps_offset;
    uint32_t early  = p->h.insdshead->ksmps_no_end;

    /* sample-accurate mode mechanism */
    if(offset) memset(aout, '\0', offset*sizeof(MYFLT));
    if(early) {
            n -= early;
            memset(&aout[n], '\0', early*sizeof(MYFLT));
    }

    if(cnt > p->var2) cnt = (MYFLT) 0; /* check bounds */

    /* processing loop    */
    for(i=offset; i < n; i++) aout[i] = *(p->in1) + cnt;

    p->var1 = cnt; /* keep the value of cnt */
    return OK;
}

static OENTRY localops[] = {
{ "newopc", sizeof(newopc), 0, 7, "s", "kki",(SUBR) newopc_init,
(SUBR) newopc_process_control, (SUBR) newopc_process_audio }
};

LINKAGE

You build it and load it as explained in Floss Manual.

If you prefer to work in C++ this is a very accessible framework for developing Csound opcodes:

https://vlazzarini.github.io/cpof/

Yes I do :nerd_face: thanks for the tip @rory