Theading and OpenLibrary/GetFunction (Csound.dll)

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

Theading and OpenLibrary/GetFunction (Csound.dll)

Post by soren »

I believe the following demonstrates some kind of bug.

To run the code one must 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.

When the space bar is pressed the sound of test.wav will be audible until the space bar is again released.

The code works fine unless the line:

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")
is replaced by:

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")
in this case the space bar function becomes very 'unresponsive' - the timing of the audio becomes very unprecise/'random'.

I think this is not simply a performance problem within Csound, because some equivalent code I made with .NET/C# does not exhibit this problem.

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 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
Aleks_Longard
User
User
Posts: 64
Joined: Mon Dec 24, 2012 9:07 am
Location: Ukraine

Re: Theading and OpenLibrary/GetFunction (Csound.dll)

Post by Aleks_Longard »

Sory my bad english
infratec
Always Here
Always Here
Posts: 7681
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Theading and OpenLibrary/GetFunction (Csound.dll)

Post by infratec »

@Soren

So what exactly is the PB bug?

The function is called correct, else your first example would also not work.
The only difference I can see, is the length of the parameter. But since this is a pointer it should be not a problem.

If it is really the length, redue the length down to the point where it works.
Then check the code of csound and your import stuff if there is something which can be related.

'I call something from a foreign code and it is not working' is not really a PB bug.

I wrote many wrappers for other dlls and they all work without problems.
If there is a bug, I think I would noticed that already.
soren
User
User
Posts: 13
Joined: Sat Mar 28, 2020 5:38 pm

Re: Theading and OpenLibrary/GetFunction (Csound.dll)

Post by soren »

@Aleks - sorry I was off from the forum for a while, would like to check your code! however, seems the link is now dead?

@infratec - sure, maybe 'problem' is a more accurate word:) What I was trying to say is that I wrote some code with C#/.NET that does exactly the same as the PB code above (I can post the code, if you are interested), but with C# I am not experiencing this performance problem - or whatever it is..

Note that I have tried giving maximum priority for the thread that is created with CreateThread, but the problem is still there.

I wonder if this could be connected with how C#/.NET may be able to use multiple processor cores, where PureBasic does not - perhaps something like that could be causing the difference?
sq4
User
User
Posts: 98
Joined: Wed Feb 26, 2014 3:16 pm
Contact:

Re: Theading and OpenLibrary/GetFunction (Csound.dll)

Post by sq4 »

soren wrote:@Aleks - sorry I was off from the forum for a while, would like to check your code! however, seems the link is now dead?

@infratec - sure, maybe 'problem' is a more accurate word:) What I was trying to say is that I wrote some code with C#/.NET that does exactly the same as the PB code above (I can post the code, if you are interested), but with C# I am not experiencing this performance problem - or whatever it is..

Note that I have tried giving maximum priority for the thread that is created with CreateThread, but the problem is still there.

I wonder if this could be connected with how C#/.NET may be able to use multiple processor cores, where PureBasic does not - perhaps something like that could be causing the difference?
Probably this is just a wrapper :
PUBLIC void *csoundCreateThread(uintptr_t (*threadRoutine)(void *),
void *userdata);


But I am using it instead of PB CreateThread().

And now that I am here : a CSound API question:
There is a function called csoundInputMessage(), isn't there a function that sends Midi-data to a virtual midi device, instead of sending Orc(hestra)-events on the fly? I want to be able (programmaticaly) to emulate Midi input. (cfr. Cabbage and -+rtMidi=Null)
infratec
Always Here
Always Here
Posts: 7681
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Theading and OpenLibrary/GetFunction (Csound.dll)

Post by infratec »

Please test this:

Code: Select all

EnableExplicit


Structure CsoundControl
  *csound
  isStopRequested.b
  isStopped.b
EndStructure


Prototype threadRoutine(*userdata)
PrototypeC.i Proto_csoundCreateThread(*threadRoutine, *userdata)

PrototypeC Proto_ftype1(*p1)
PrototypeC.i Proto_ftype2(*p1)
PrototypeC Proto_ftype3(*p1, p2.p-ascii)
PrototypeC.i Proto_ftype4(*p1, p2.p-ascii)
PrototypeC.i Proto_ftype5(*p1, *p2, p3.i)

Global csoundCreate.Proto_ftype2
Global csoundSetOption.Proto_ftype4
Global csoundCompileOrc.Proto_ftype4
Global csoundStart.Proto_ftype2
Global csoundStop.Proto_ftype1
Global csoundReset.Proto_ftype1
Global csoundDestroy.Proto_ftype1
Global csoundPerformKsmps.Proto_ftype2
Global csoundInputMessage.Proto_ftype3
Global csoundGetAudioDevList.Proto_ftype5
Global csoundCreateThread.Proto_csoundCreateThread


Global CSoundDLL.i

Procedure.i LoadCSoundDLL()
  
  CSoundDLL = OpenLibrary(#PB_Any, "csound64.dll")
  If CSoundDLL
    csoundCreate = GetFunction(CSoundDLL, "csoundCreate")
    csoundSetOption = GetFunction(CSoundDLL, "csoundSetOption")
    csoundCompileOrc = GetFunction(CSoundDLL, "csoundCompileOrc")
    csoundStart = GetFunction(CSoundDLL, "csoundStart")
    csoundStop = GetFunction(CSoundDLL, "csoundStop")
    csoundReset = GetFunction(CSoundDLL, "csoundReset")
    csoundDestroy = GetFunction(CSoundDLL, "csoundDestroy")
    csoundPerformKsmps = GetFunction(CSoundDLL, "csoundPerformKsmps")
    csoundInputMessage = GetFunction(CSoundDLL, "csoundInputMessage")
    csoundGetAudioDevList = GetFunction(CSoundDLL, "csoundGetAudioDevList")
    
    csoundCreateThread.Proto_csoundCreateThread = GetFunction(CSoundDLL, "csoundCreateThread")
  EndIf
  
  ProcedureReturn CSoundDLL
  
EndProcedure



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

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

Procedure SetUpCsound(*ctrl.CsoundControl)
  
  Protected File.i, S$
  
  *ctrl\csound = csoundCreate(#Null)
  If *ctrl\csound
    
    csoundSetOption(*ctrl\csound, "-odac")
    csoundSetOption(*ctrl\csound, "-b1024")
    csoundSetOption(*ctrl\csound, "-B1024")
    
    File = ReadFile(#PB_Any, "test.orc")
    If File
      While Not Eof(File)
        S$ + ReadString(File) + #LF$
      Wend
      CloseFile(File)
      csoundCompileOrc(*ctrl\csound, S$)
    EndIf
    
    S$ = "f 16 0 0 -1 " + #DQUOTE$ + "test.wav" + #DQUOTE$ + " 0 0 0"
    csoundInputMessage(*ctrl\csound, S$)
    
    S$ = "i 96.0 0 -1 0" + #LF$
    S$ + "i 96.1 0 -1 1" + #LF$
    S$ + "i 96.2 0 -1 ch2" + #LF$
    S$ + "i 98 0 -1"
    csoundInputMessage(*ctrl\csound, S$)
    
    csoundStart(*ctrl\csound)
    ;CreateThread(@CsoundThread(), ctrl)
    csoundCreateThread(@CsoundThread(), *ctrl)
  EndIf
EndProcedure

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

Procedure RunApp(*ctrl.CsoundControl)
  
  Protected.i Event, playindex, Exit, isspacepressed
  Protected f$, s$
  
  
  Repeat
    Repeat
      Event = WindowEvent()
      Select Event
        Case #PB_Event_CloseWindow
          CleanUpAndQuit(*ctrl)
          Exit = #True
      EndSelect
    Until Event = 0
    
    If Not Exit
      FlipBuffers()
      ExamineKeyboard()
      
      f$ = "10." + RSet(Str(playindex), 6, "0")
      
      If KeyboardPushed(#PB_Key_Space) And Not isspacepressed
        
        s$ = "i -" + f$ + " 0 -1 " + #LF$
        s$ + "i  " + f$ + " 0 -1 " + Str(playindex) + " 0.5" + #LF$
        s$ + "i -" + f$ + " 0.25 -1 " + #LF$
        s$ + "i  " + f$ + " 0.25 -1 " + Str(playindex) + " 0.375" + #LF$
        s$ + "i -" + f$ + " 0.5 -1 " + #LF$
        s$ + "i  " + f$ + " 0.5 -1 " + Str(playindex) + " 0.25" + #LF$
        s$ + "i -" + f$ + " 0.75 -1 " + #LF$
        s$ + "i  " + f$ + " 0.75 -1 " + Str(playindex) + " 0.5" + #LF$
        s$ + "i -" + f$ + " 1 -1 " + #LF$
        s$ + "i  " + f$ + " 1 -1 " + Str(playindex) + " 0.375" + #LF$
        s$ + "i -" + f$ + " 1.25 -1 " + #LF$
        s$ + "i  " + f$ + " 1.25 -1 " + Str(playindex) + " 0.25" + #LF$
        s$ + "i -" + f$ + " 1.5 -1 " + #LF$
        s$ + "i  " + f$ + " 1.5 -1 " + Str(playindex) + " 0.5" + #LF$
        s$ + "i -" + f$ + " 1.75 -1 " + #LF$
        s$ + "i  " + f$ + " 1.75 -1 " + Str(playindex) + " 0.375"
        
        csoundInputMessage(*ctrl\csound, s$)
        
        isspacepressed = #True
      EndIf
      
      If Not KeyboardPushed(#PB_Key_Space) And isspacepressed
        
        playindex + 1
        s$ = "i 1 0 0.1 " + Str(playindex) + #LF$
        s$ + "i -" + f$ + " 0 -1"
        csoundInputMessage(*ctrl\csound, s$)
        isspacepressed = #False
      EndIf
      
    EndIf
  Until Exit
  
EndProcedure


;-main
Define ctrl.CsoundControl

If LoadCSoundDLL()
  SetUpCsound(@ctrl)
  SetupUi()
  RunApp(@ctrl)
EndIf
I adjusted some prototypes and added the CreateThread form the dll.
It works here without any problems.
soren
User
User
Posts: 13
Joined: Sat Mar 28, 2020 5:38 pm

Re: Theading and OpenLibrary/GetFunction (Csound.dll)

Post by soren »

@infratec - thanks for trying this out! your example also works fine here, but if you replace

Code: Select all

S$ = "i 96.0 0 -1 0" + #LF$
S$ + "i 96.1 0 -1 1" + #LF$
S$ + "i 96.2 0 -1 ch2" + #LF$
S$ + "i 98 0 -1"
with:

Code: Select all

S$ = "i 96.0 0 -1 0" + #LF$
S$ + "i 96.1 0 -1 1" + #LF$
S$ + "i 96.2 0 -1 2" + #LF$
S$ + "i 96.3 0 -1 3" + #LF$
S$ + "i 96.4 0 -1 4" + #LF$
S$ + "i 96.5 0 -1 5" + #LF$
S$ + "i 96.6 0 -1 6" + #LF$
S$ + "i 96.7 0 -1 7" + #LF$
S$ + "i 96.8 0 -1 8" + #LF$
S$ + "i 96.9 0 -1 9" + #LF$
S$ + "i 96.10 0 -1 10" + #LF$
S$ + "i 96.11 0 -1 11" + #LF$
S$ + "i 96.12 0 -1 12" + #LF$
S$ + "i 96.13 0 -1 13" + #LF$
S$ + "i 96.14 0 -1 14" + #LF$
S$ + "i 98 0 -1"
(as in the original code - each i-statement makes Csound work a bit harder) - the problem still exists..:(
Post Reply