Csound Csound-dev Csound-tekno Search About

[Csnd-dev] sensekey in bus.c

Date2016-02-26 00:00
FromTarmo Johannes
Subject[Csnd-dev] sensekey in bus.c
Hi,

I am trying to debug an old problem with CsoundQt that sensekey does not work when used within CsoundQt, see
https://sourceforge.net/p/csound/mailman/csound-users/thread/55BFA6CF.9070903@joachimheintz.de/

In fact it does, if to start CsoundQt binary from terminal or QtCreator or  even if to click on it  in file manager (Linux).
But if to start the program via a desktop file (like from start menu), it does not -  the sensekey.csd example from manual returns error:

PERF ERROR in instr 1: read failure in sensekey


k1 k2 sensekey

note aborted



CsoundQt catches the keyboard events correctly and forwards them to Csound API via csoundRegisterKeyboardCallback:

csoundRegisterKeyboardCallback(ud->csound,  &CsoundEngine::keyEventCallback,
                                   (void *) ud, CSOUND_CALLBACK_KBD_EVENT | CSOUND_CALLBACK_KBD_TEXT);


I tested that the key is correctly there in CsoundQt side but the problem happens somehow in between or in Csound. The callback fuction in CsoundQt is (csoundengine.cpp:401-427) :

int CsoundEngine::keyEventCallback(void *userData,
                                   void *p,
                                   unsigned int type)
{
    if (type != CSOUND_CALLBACK_KBD_EVENT && type != CSOUND_CALLBACK_KBD_TEXT) {
        return 1;
    }
    CsoundUserData *ud = (CsoundUserData *) userData;
    //  WidgetLayout *wl = (WidgetLayout *) ud->wl;
    int *value = (int *) p;
    int key = ud->csEngine->popKeyPressEvent();
    QString command = "oscsend localhost 9990 /keyEventCallback i " + QString::number(key);
    if (key!=-1)
        system(command.toLocal8Bit() ); // FOR TESTING
    if (key >= 0) {
        *value = key;
//            qDebug() << "Pressed: " << key;
    }
    else if (type & CSOUND_CALLBACK_KBD_EVENT) {
        key = ud->csEngine->popKeyReleaseEvent();
        if (key >= 0) {
            *value = key | 0x10000;
            //       qDebug() << "Released: " << key;
        }
    }
    return 0;
}



From the sent OSC message (since I cannot test it in terminal) I can see, that key value is correct  here before the sensekey error happens.


I found the part in Csound code that is responsible for that is in Oops/bus.c function sensekey_perf (line 1298- ). I must say I don't understand it completely. Can you help me further, is there anything I can do from Qt side to make the connetion work?

As I undertstand correctly, the error detected here (l. 1334-)

 retval = select(1, &rfds, NULL, NULL, &tv);

        if (retval) {
          char    ch = '\0';
          if (UNLIKELY(read(0, &ch, 1)!=1)) {
            csound->PerfError(csound, p->h.insdshead,
                              Str("read failure in sensekey\n"));
            return NOTOK;
          }
          keyCode = (int)((unsigned char) ch);
          /* FD_ISSET(0, &rfds) will be true. */
        }

i.e. ' read(0, &ch, 1)' fails. Do I read correctly that it tries to read one byte from file/FIFO 0 (probably standard input) to vairable 'ch'? How does the callback function send its informatio to there?  What does the select() line above do?

I hope you can enlighten me and give some hints, what to try out.

Thanks!
tarmo




Date2016-02-26 06:55
FromVictor Lazzarini
SubjectRe: [Csnd-dev] sensekey in bus.c
read(0,...) is trying to read from stdin as far as I can see. 0 is the fd for stdin. But if there is no stdin, then it won't work.

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

On 26 Feb 2016, at 00:00, Tarmo Johannes <trmjhnns@GMAIL.COM> wrote:

Hi,

I am trying to debug an old problem with CsoundQt that sensekey does not work when used within CsoundQt, see
https://sourceforge.net/p/csound/mailman/csound-users/thread/55BFA6CF.9070903@joachimheintz.de/

In fact it does, if to start CsoundQt binary from terminal or QtCreator or  even if to click on it  in file manager (Linux).
But if to start the program via a desktop file (like from start menu), it does not -  the sensekey.csd example from manual returns error:

PERF ERROR in instr 1: read failure in sensekey


k1 k2 sensekey

note aborted



CsoundQt catches the keyboard events correctly and forwards them to Csound API via csoundRegisterKeyboardCallback:

csoundRegisterKeyboardCallback(ud->csound,  &CsoundEngine::keyEventCallback,
                                   (void *) ud, CSOUND_CALLBACK_KBD_EVENT | CSOUND_CALLBACK_KBD_TEXT);


I tested that the key is correctly there in CsoundQt side but the problem happens somehow in between or in Csound. The callback fuction in CsoundQt is (csoundengine.cpp:401-427) :

int CsoundEngine::keyEventCallback(void *userData,
                                   void *p,
                                   unsigned int type)
{
    if (type != CSOUND_CALLBACK_KBD_EVENT && type != CSOUND_CALLBACK_KBD_TEXT) {
        return 1;
    }
    CsoundUserData *ud = (CsoundUserData *) userData;
    //  WidgetLayout *wl = (WidgetLayout *) ud->wl;
    int *value = (int *) p;
    int key = ud->csEngine->popKeyPressEvent();
    QString command = "oscsend localhost 9990 /keyEventCallback i " + QString::number(key);
    if (key!=-1)
        system(command.toLocal8Bit() ); // FOR TESTING
    if (key >= 0) {
        *value = key;
//            qDebug() << "Pressed: " << key;
    }
    else if (type & CSOUND_CALLBACK_KBD_EVENT) {
        key = ud->csEngine->popKeyReleaseEvent();
        if (key >= 0) {
            *value = key | 0x10000;
            //       qDebug() << "Released: " << key;
        }
    }
    return 0;
}



From the sent OSC message (since I cannot test it in terminal) I can see, that key value is correct  here before the sensekey error happens.


I found the part in Csound code that is responsible for that is in Oops/bus.c function sensekey_perf (line 1298- ). I must say I don't understand it completely. Can you help me further, is there anything I can do from Qt side to make the connetion work?

As I undertstand correctly, the error detected here (l. 1334-)

 retval = select(1, &rfds, NULL, NULL, &tv);

        if (retval) {
          char    ch = '\0';
          if (UNLIKELY(read(0, &ch, 1)!=1)) {
            csound->PerfError(csound, p->h.insdshead,
                              Str("read failure in sensekey\n"));
            return NOTOK;
          }
          keyCode = (int)((unsigned char) ch);
          /* FD_ISSET(0, &rfds) will be true. */
        }

i.e. ' read(0, &ch, 1)' fails. Do I read correctly that it tries to read one byte from file/FIFO 0 (probably standard input) to vairable 'ch'? How does the callback function send its informatio to there?  What does the select() line above do?

I hope you can enlighten me and give some hints, what to try out.

Thanks!
tarmo




Date2016-02-26 15:15
Fromjpff
SubjectRe: [Csnd-dev] sensekey in bus.c

On Fri, 26 Feb 2016, Tarmo Johannes wrote:

> 
> As I undertstand correctly, the error detected here (l. 1334-)
> 
>  retval = select(1, &rfds, NULL, NULL, &tv);
> 
>         if (retval) {
>           char    ch = '\0';
>           if (UNLIKELY(read(0, &ch, 1)!=1)) {
>             csound->PerfError(csound, p->h.insdshead,
>                               Str("read failure in sensekey\n"));
>             return NOTOK;
>           }
>           keyCode = (int)((unsigned char) ch);
>           /* FD_ISSET(0, &rfds) will be true. */
>         }
> 
> i.e. ' read(0, &ch, 1)' fails. Do I read correctly that it tries to read one
> byte from file/FIFO 0 (probably standard input) to vairable 'ch'? How does the
> callback function send its informatio to there?  What does the select() line
> above do?
>

On the other hand the code before that says
         FD_ZERO(&rfds);
         FD_SET(0, &rfds);
         /* No waiting */
         tv.tv_sec = 0;
         tv.tv_usec = 0;

         retval = select(1, &rfds, NULL, NULL, &tv);

so it looks too see if there is a character waiting on fd 0 immediately.
This code is MACH and unix only by the way
==John


Date2016-02-26 16:19
Fromjpff
SubjectRe: [Csnd-dev] sensekey in bus.c
Ps that would be better read as
.....
  if (retval>0) {
......

which would ignore errors.  Will adjust the  code now

Date2016-02-26 17:14
FromTarmo Johannes
SubjectRe: [Csnd-dev] sensekey in bus.c
Thanks,

pulled from git and tested but that does not solve the problem.
Seems that stdin is not available when the program is not started from terminal.

Is there something to do? I tried to add  <&0  behind the execution command in destop file:

[Desktop Entry]
Exec=bash -c /home/tarmo/src/qutecsound/build-qcs-Qt5_desktop-Debug/bin/CsoundQt-d-py-cs6-debug  %F <&0

but it did not work.  I don't understand the piping or redirections so well, too....

And it still it puzzles me - CsoundQt has the key info, keyboard callback is set, but the info gets lost.
How does csoundRegisterKeyboardCallback work and how can the key event arrive into stdin that sensekey is reading exlusively?

Can this be also  it a timing issue?

One way is of course to start CsoundQt always from terminal but this does not seem so neat...


Thanks!

tarmo

2016-02-26 18:19 GMT+02:00 jpff <jpff@codemist.co.uk>:
Ps that would be better read as
.....
 if (retval>0) {
......

which would ignore errors.  Will adjust the  code now
==Jon


Date2016-02-26 17:31
Fromjpff
SubjectRe: [Csnd-dev] sensekey in bus.c
I have not found a way of getting key information on GNU/Linux and this 
code looks right.  If fd 0 does not exist I cannot see ow it can be 
reported as ready to read.
   There is a cryptic remark in the man page for select that suggests a fd 
at EOF could be reported as ready.  I suppose one could persue that idea? 
I will look at further code changes


On Fri, 26 Feb 2016, Tarmo Johannes wrote:

> Thanks,
> 
> pulled from git and tested but that does not solve the problem.
> Seems that stdin is not available when the program is not started from
> terminal.
> 
> Is there something to do? I tried to add  <&0  behind the execution command in
> destop file:
> 
> [Desktop Entry]
> Exec=bash -c/home/tarmo/src/qutecsound/build-qcs-Qt5_desktop-Debug/bin/CsoundQt-d-py-cs6-
> debug  %F <&0
> 
> but it did not work.  I don't understand the piping or redirections so well,
> too....
> 
> And it still it puzzles me - CsoundQt has the key info, keyboard callback is
> set, but the info gets lost.
> How does csoundRegisterKeyboardCallback work and how can the key event arrive
> into stdin that sensekey is reading exlusively?
> 
> Can this be also  it a timing issue?
> 
> One way is of course to start CsoundQt always from terminal but this does not
> seem so neat...
> 
> 
> Thanks!
> 
> tarmo
> 
> 2016-02-26 18:19 GMT+02:00 jpff :
>       Ps that would be better read as
>       .....
>        if (retval>0) {
>       ......
>
>       which would ignore errors.  Will adjust the  code now
>       ==Jon
> 
> 
> 
>

Date2016-02-26 17:44
Fromjpff
SubjectRe: [Csnd-dev] sensekey in bus.c
I added code to handle EOF

Date2016-03-02 22:37
FromTarmo Johannes
SubjectRe: [Csnd-dev] sensekey in bus.c

Hi,

 

Just for information I am reporting back that I solved the issue in CsoundQt by sending a dummy keypress to Csound right after registering the keyboard Callback:

 

#ifdef CSOUND6

csoundRegisterKeyboardCallback(ud->csound, &CsoundEngine::keyEventCallback, (void *) ud, CSOUND_CALLBACK_KBD_EVENT | CSOUND_CALLBACK_KBD_TEXT);

 

csoundKeyPress(getCsound(),'\0'); // necessary to put something into the buffer, otherwise sensekey complains when not started from terminal

 

#else

...

 

Now sensekey works as expected also when the program is not started from terminal.

 

Looking again at the sensekey code in bus.c, is'nt it so that if a callback is set, the conditions should be so that the function should not check for stdin at all? Probably I am still not understanding the code completely.

 

Anyway, it is fine now with that matter.

 

Thanks!

tarmo

 

 

 

 

On Friday 26 February 2016 17:44:34 you wrote:

> I added code to handle EOF

> Not sure this is the answer but it is better