Unstable OpenLibrary/GetFunction calls (Csound)

Just starting out? Need help? Post your questions and find answers here.
soren
User
User
Posts: 13
Joined: Sat Mar 28, 2020 5:38 pm

Unstable OpenLibrary/GetFunction calls (Csound)

Post by soren »

Can someone please help me verify if this could be a bug in Purebasic - or perhaps I'm doing something wrong?

If you run the code and press the space bar quickly/repeatedly you can hear from the sound output that the imported function csoundInputMessage() will soon start to be called at more 'random' times, and sometimes not at all - it should be called immediately when the space bar is pressed (releasing the space bare should stop the 'music').

To run the code you need to install Csound and put a stereo sample (test.wav) and the Csound definition below (test.orc) in the same folder as the pb code file.

Note that I have recreated this same code using .NET/C# where the problem doesn't appear, which is why I am suspecting there is a problem with Purebasic (or how I'm using Purebasic). Also note that the problem seems somehow connected with how 'busy' the Csound process is - the code is starting a lot of 'heavy' delay processing via 'i 96.x' statements - if some of these statements are remove the problem does not start as soon.

Note: could this somehow be related with the priority of the thread that is started? Is there a way to give it higher priority?

Code: Select all

OpenLibrary(0, "csound64.dll")

Structure CsoundControl
  *csound
  isStopRequested.b
  isStopped.b
EndStructure

Global isspacepressed.b
Global ctrl.CsoundControl

PrototypeC.l ftype1()
PrototypeC.i ftype2(*p1)
PrototypeC.i ftype3(*p1, p2.p-ascii)
PrototypeC.i ftype4(*p1, *p2, p3.i)

Global csoundCreate.ftype1        = GetFunction(0, "csoundCreate")
Global csoundSetOption.ftype3     = GetFunction(0, "csoundSetOption")
Global csoundCompileOrc.ftype3    = GetFunction(0, "csoundCompileOrc")
Global csoundStart.ftype2         = GetFunction(0, "csoundStart")
Global csoundStop.ftype2          = GetFunction(0, "csoundStop")
Global csoundReset.ftype2         = GetFunction(0, "csoundReset")
Global csoundDestroy.ftype2       = GetFunction(0, "csoundDestroy")
Global csoundPerformKsmps.ftype2  = GetFunction(0, "csoundPerformKsmps")
Global csoundInputMessage.ftype3  = GetFunction(0, "csoundInputMessage")
Global csoundGetAudioDevList.ftype2 = GetFunction(0, "csoundGetAudioDevList")

Procedure CsoundThread(*ctrl.CsoundControl)
  While Not csoundPerformKsmps(*ctrl\csound) And Not *ctrl\isStopRequested : Wend
  *ctrl\isStopped = #True
EndProcedure

Procedure CleanUpAndQuit()
  If ctrl\csound
    ctrl\isStopRequested = #True
    While Not ctrl\isStopped
      Delay(1)
    Wend
    csoundStop(ctrl\csound)
    csoundReset(ctrl\csound)
    csoundDestroy(ctrl\csound)
  EndIf
  End
EndProcedure

Procedure SetUpCsound()
  s.s = ""
  ReadFile(0, "test.orc")
  While Eof(0) = 0
    s = s + ReadString(0) + Chr(10)
  Wend
  CloseFile(0)
  
  ctrl\csound = csoundCreate()

  csoundSetOption(ctrl\csound, "-odac")
  csoundSetOption(ctrl\csound, "-b1024")
  csoundSetOption(ctrl\csound, "-B1024")
  csoundCompileOrc(ctrl\csound, s)
  
  csoundInputMessage(ctrl\csound, "f 16 0 0 -1 " + Chr(34) + "test.wav" + Chr(34) + " 0 0 0")
  
  csoundInputMessage(ctrl\csound, "i 96.0 0 -1 0" + Chr(10) + "i 96.1 0 -1 1" + Chr(10) + "i 96.2 0 -1 ch2" + Chr(10) + 
                                  "i 96.3 0 -1 3" + Chr(10) + "i 96.4 0 -1 4" + Chr(10) + "i 96.5 0 -1 5" + Chr(10) + 
                                  "i 96.6 0 -1 6" + Chr(10) + "i 96.7 0 -1 7" + Chr(10) + "i 96.8 0 -1 8" + Chr(10) +
                                  "i 96.9 0 -1 9" + Chr(10) + "i 96.10 0 -1 10" + Chr(10) + "i 96.11 0 -1 11" + Chr(10) +
                                  "i 96.12 0 -1 12" + Chr(10) + "i 96.13 0 -1 13" + Chr(10) + "i 96.14 0 -1 14" + Chr(10) +
                                  "i 98 0 -1")
  
  csoundStart(ctrl\csound)
  CreateThread(@CsoundThread(), ctrl)
EndProcedure

Procedure SetupUi()
  InitSprite()
  InitKeyboard()
  OpenWindow(0, 0, 0, 600, 400, "Test")
  OpenWindowedScreen(WindowID(0), 10000, 10000, 20, 20)
EndProcedure

Procedure RunApp()
  playindex = 0
  
  Repeat
    Repeat
      event = WindowEvent()
      Select event
        Case #PB_Event_CloseWindow
          CleanUpAndQuit()
      EndSelect
    Until event = 0 ;empty the event queue
    
    FlipBuffers()
    ExamineKeyboard()
    
    f.s = "10." + Right("000000" + Str(playindex), 6)
    
    If KeyboardPushed(#PB_Key_Space) And Not isspacepressed
      
      csoundInputMessage(ctrl\csound, "i -" + f + " 0 -1 " + Chr(10) +
        "i  " + f + " 0 -1  " + playindex + " 0.5 " + Chr(10) +
        "i -" + f + " 0.25 -1 " + Chr(10) +
        "i  " + f + " 0.25 -1  " + playindex + " 0.375 " + Chr(10) +
        "i -" + f + " 0.5 -1 " + Chr(10) +
        "i  " + f + " 0.5 -1  " + playindex + " 0.25 " + Chr(10) +
        "i -" + f + " 0.75 -1 " + Chr(10) +
        "i  " + f + " 0.75 -1  " + playindex + " 0.5 " + Chr(10) +
        "i -" + f + " 1 -1 " + Chr(10) +
        "i  " + f + " 1 -1  " + playindex + " 0.375 " + Chr(10) +
        "i -" + f + " 1.25 -1 " + Chr(10) +
        "i  " + f + " 1.25 -1  " + playindex + " 0.25 " + Chr(10) +
        "i -" + f + " 1.5 -1 " + Chr(10) +
        "i  " + f + " 1.5 -1  " + playindex + " 0.5 " + Chr(10) +
        "i -" + f + " 1.75 -1 " + Chr(10) +
        "i  " + f + " 1.75 -1  " + playindex + " 0.375 ")

      isspacepressed = #True
    EndIf
    
    If Not KeyboardPushed(#PB_Key_Space) And isspacepressed
      
      playindex + 1
      csoundInputMessage(ctrl\csound, "i 1 0 0.1 " + playindex + Chr(10) +
                                      "i -" + f + " 0 -1")
      isspacepressed = #False
    EndIf
  ForEver
EndProcedure

OnErrorCall(@CleanUpAndQuit())

SetUpCsound()
SetupUi()
RunApp()
test.orc:

Code: Select all

sr=44100
ksmps=10
nchnls=2
0dbfs=1

gisine     ftgen      0, 0, 128, 10, 1
gicurplay  init       0

gireldur     init       0.13
gaal[]       init  100
gaar[]       init  100

instr 1
gicurplay init p4
endin

instr 10
             cggoto      p4 != gicurplay, finish
             tigoto      output
al, ar       loscil3     0.7, pow(2, (p5 - 0.5) * 2), 16, 1, 0
             output:
             gaal[0] = al
             gaar[0] = ar
             finish:
endin

instr 96
al              =              gaal[p4]
ar              =              gaar[p4]

asin            oscili         0.001, 1, gisine

adt1            =              1.1 + asin
adt2            =              1.2 + asin
adt3            =              1.3 + asin
adt4            =              1.4 + asin
adt5            =              1.5 + asin
adt6            =              1.6 + asin
adt7            =              1.7 + asin
adt8            =              1.8 + asin

adl            delayr         2
atap1l         deltap3        adt1
atap2l         deltap3        adt3
atap3l         deltap3        adt5
atap4l         deltap3        adt7
               delayw         al + (atap1l + atap2l + atap3l + atap4l) / 4 * 0.2
al             =              al + (atap1l + atap2l + atap3l + atap4l) / 4 * 0.6

adr            delayr         2
atap1r         deltap3        adt2
atap2r         deltap3        adt4
atap3r         deltap3        adt6
atap4r         deltap3        adt8
               delayw         ar + (atap1r + atap2r + atap3r + atap4r) / 4 * 0.2
ar             =              ar + (atap1r + atap2r + atap3r + atap4r) / 4 * 0.6

gaal[p4]       =              al
gaar[p4]       =              ar

endin

instr 98
al             =              gaal[0]
ar             =              gaar[0]
               outs           al, ar
gaal[0]        =              0
gaar[0]        =              0
endin
infratec
Always Here
Always Here
Posts: 7681
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Unstable OpenLibrary/GetFunction calls (Csound)

Post by infratec »

Hm ... it works for me,

but I changed:

Code: Select all

Global csoundCreate.ftype2        = GetFunction(0, "csoundCreate")
and

Code: Select all

ctrl\csound = csoundCreate(0)
soren
User
User
Posts: 13
Joined: Sat Mar 28, 2020 5:38 pm

Re: Unstable OpenLibrary/GetFunction calls (Csound)

Post by soren »

@infratec thanks for testing! sure it kind of 'works' but maybe I should have mentioned that I expect this to have very precise timing and 'reponsiveness' - it should be usable as a type of music performance instrument, that is, if using an ASIO driver (ASIO4ALL).. but even with a the normal directx driver I would expect less randomness in the timing..

if you replace

Code: Select all

csoundInputMessage(ctrl\csound, "i 96.0 0 -1 0" + Chr(10) + "i 96.1 0 -1 1" + Chr(10) + "i 96.2 0 -1 ch2" + Chr(10) + 
                                  "i 96.3 0 -1 3" + Chr(10) + "i 96.4 0 -1 4" + Chr(10) + "i 96.5 0 -1 5" + Chr(10) + 
                                  "i 96.6 0 -1 6" + Chr(10) + "i 96.7 0 -1 7" + Chr(10) + "i 96.8 0 -1 8" + Chr(10) +
                                  "i 96.9 0 -1 9" + Chr(10) + "i 96.10 0 -1 10" + Chr(10) + "i 96.11 0 -1 11" + Chr(10) +
                                  "i 96.12 0 -1 12" + Chr(10) + "i 96.13 0 -1 13" + Chr(10) + "i 96.14 0 -1 14" + Chr(10) +
                                  "i 98 0 -1")
with

Code: Select all

csoundInputMessage(ctrl\csound, "i 96.0 0 -1 0" + Chr(10) + "i 96.1 0 -1 1" + Chr(10) + "i 96.2 0 -1 ch2" + Chr(10) + 
                                  "i 98 0 -1")
doesn't it give you much better timing?

N.B. I don't think it should make a difference between these two versions, because with the .NET/C# version of my code, it doesn't.
Post Reply