Chinaunix首页 | 论坛 | 博客
  • 博客访问: 281732
  • 博文数量: 17
  • 博客积分: 2096
  • 博客等级: 大尉
  • 技术积分: 535
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-28 18:55
文章分类

全部博文(17)

文章存档

2010年(16)

2008年(5)

分类: C/C++

2010-06-12 23:18:49

 
Join Date
Feb 2007
Location
Karlsruhe, Germany
Posts
238
Thanks
11
Thanked 36 Times in 36 Posts
Qt products
Qt4
Platforms
Windows

Default Re: emit a signal from inside a callback routine

All right, I give up :->

So your solution is to just emit the signal through the singleton?

Qt Code:
  1. class AudioDevice : public
  2. { Q_OBJECT
  3. friend FMOD_RESULT F_CALLBACK endCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type,
  4. unsigned int commanddata1, unsigned int commanddata2);
  5.  
  6. public:
  7. static AudioDevice* singleton()
  8. {
  9. if (!instance)
  10. instance = new AudioDevice();
  11. return instance;
  12. }
  13. signals:
  14. void soundStopped();
  15.  
  16. protected:
  17. AudioDevice() {}
  18.  
  19. private:
  20. static AudioDevice *instance;
  21. };
  22.  
  23. AudioDevice* AudioDevice::instance = 0;
  24.  
  25. FMOD_RESULT F_CALLBACK endCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type,
  26. unsigned int commanddata1, unsigned int commanddata2)
  27. {
  28. ..
  29. emit AudioDevice::singleton()->soundStopped();
  30. ..
  31. }
To copy to clipboard, switch view to plain text mode 
HIH

Johannes
 

  • Join Date
    Nov 2007
    Location
    Italy
    Posts
    354
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: emit a signal from inside a callback routine

    Quote Originally Posted by JohannesMunk View Post
    All right, I give up :->

    So your solution is to just emit the signal through the singleton?

    Qt Code:
    1. class AudioDevice : public
    2. { Q_OBJECT
    3. friend FMOD_RESULT F_CALLBACK endCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type,
    4. unsigned int commanddata1, unsigned int commanddata2);
    5.  
    6. public:
    7. static AudioDevice* singleton()
    8. {
    9. if (!instance)
    10. instance = new AudioDevice();
    11. return instance;
    12. }
    13. signals:
    14. void soundStopped();
    15.  
    16. protected:
    17. AudioDevice() {}
    18.  
    19. private:
    20. static AudioDevice *instance;
    21. };
    22.  
    23. AudioDevice* AudioDevice::instance = 0;
    24.  
    25. FMOD_RESULT F_CALLBACK endCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type,
    26. unsigned int commanddata1, unsigned int commanddata2)
    27. {
    28. ..
    29. emit AudioDevice::singleton()->soundStopped();
    30. ..
    31. }
    To copy to clipboard, switch view to plain text mode 
    HIH

    Johannes
    Hi I didn't well understand the difference between your last code and the code you suggested to me before.
    Can you explain to me?
    Best Regards
    Franco Amato
     

  • Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    238
    Thanks
    11
    Thanked 36 Times in 36 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: emit a signal from inside a callback routine

    Sure!

    The only difference is how we get a pointer to our audiodevice from inside the callback.

    The first approach used the callbacks commanddata to get a reference to the audiodevice. That would allow for several audiodevices to exist simultaneously in your application.

    Then we found out, that you can't set the commanddata for that purpose.

    Then you said, that you have only one (singleton) audiodevice. That means that we can easily access this single (global) audiodevice.. to emit the signal from everywhere we want. In the way I have shown to you (friends + singleton access)

    And once the signal gets emitted correctly the common signal slot mechanism - which I didn't show how to setup - will assure that your currentsound will "get the message"!

    Let me know if I was talking sense now :->

    Johannes
     

  • Join Date
    Nov 2007
    Location
    Italy
    Posts
    354
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: emit a signal from inside a callback routine

    Quote Originally Posted by JohannesMunk View Post
    Sure!

    The only difference is how we get a pointer to our audiodevice from inside the callback.

    The first approach used the callbacks commanddata to get a reference to the audiodevice. That would allow for several audiodevices to exist simultaneously in your application.

    Then we found out, that you can't set the commanddata for that purpose.

    Then you said, that you have only one (singleton) audiodevice. That means that we can easily access this single (global) audiodevice.. to emit the signal from everywhere we want. In the way I have shown to you (friends + singleton access)

    And once the signal gets emitted correctly the common signal slot mechanism - which I didn't show how to setup - will assure that your currentsound will "get the message"!

    Let me know if I was talking sense now :->

    Johannes
    Yes sure. Thank you very much your explanation was clear.
    A question. I would connect with the signal/slot mechanism 2 objects ( audiodevice + another one ). The problem is that eather one is part of the other.
    AudioDevice has not an instance of the OtherObject and the OtherObject has not an instance of the AudioDevice.
    The 2 objects are indipendent.

    I hpe you can help me.

    Best Regards,
    Franco
    Franco Amato
     

  • Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    238
    Thanks
    11
    Thanked 36 Times in 36 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: emit a signal from inside a callback routine

    That's perfectly fine for signals and slots:

    Qt Code:
    1. AudioDevice* ad = new AudioDevice();
    2. ...
    3. SoundData* sd = new SoundData();
    4. ...
    5. ::connect(ad,SIGNAL(soundStopped()),sd,SLOT(someSLOT()));
    To copy to clipboard, switch view to plain text mode 
    or using the singleton approach to get the AudioDevice:

    Qt Code:
    1. SoundData* sd = new SoundData();
    2. ...
    3. ::connect(AudioDevice::singleton(),SIGNAL(soundStopped()),sd,SLOT(someSLOT()));
    To copy to clipboard, switch view to plain text mode 
    For signals and slots to work both classes have to inherit someway along the line from QObject and include the Q_OBJECT macro..

    They don't have to know anything from each other. Thats the beauty of signals!

    HIH

    Johannes
    Last edited by JohannesMunk; 9th December 2009 at 02:03. Reason: forgot the QObject::
     

  • Join Date
    Nov 2007
    Location
    Italy
    Posts
    354
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: emit a signal from inside a callback routine

    Quote Originally Posted by JohannesMunk View Post
    That's perfectly fine for signals and slots:

    Qt Code:
    1. AudioDevice* ad = new AudioDevice();
    2. ...
    3. SoundData* sd = new SoundData();
    4. ...
    5. ::connect(ad,SIGNAL(soundStopped()),sd,SLOT(someSLOT()));
    To copy to clipboard, switch view to plain text mode 
    or using the singleton approach to get the AudioDevice:

    Qt Code:
    1. SoundData* sd = new SoundData();
    2. ...
    3. ::connect(AudioDevice::singleton(),SIGNAL(soundStopped()),sd,SLOT(someSLOT()));
    To copy to clipboard, switch view to plain text mode 
    For signals and slots to work both classes have to inherit someway along the line from QObject and include the Q_OBJECT macro..

    They don't have to know anything from each other. Thats the beauty of signals!

    HIH

    Johannes
    It's fantastic. I love Qt.
    In which part of the code I have to write the QObject::connect?
    In that case ( a signal emitted by a callback ) I have to specify the Queued connections flag right?

    Best
    Franco Amato
     

  • Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    238
    Thanks
    11
    Thanked 36 Times in 36 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: emit a signal from inside a callback routine

    Quote Originally Posted by franco.amato View Post
    In which part of the code I have to write the QObject::connect?
    Any. I suggest where you create the sounddata. If your sounddata is more generic than just data being played back, I suggest to set it up when you prepare it for playback. But then you will have to remove the connection after playback ended, to avoid multiple connections, when you play it back again. I don't know enough about the layout of your program to help you here..

    BTW: As the connect function is a static function of the QObject class, you only need to write "QObject::" in front of connect, if you are outside a QObject class.. Inside you can just write "connect(..)". But I showed you QObject::connect .. to underline that you can call this from everywhere.

    Quote Originally Posted by franco.amato View Post
    In that case ( a signal emitted by a callback ) I have to specify the Queued connections flag right?
    That depends on your callback library. Some execute the callback within the thread context of your application (synchronized) and some don't (async). Perhaps you can specify that when you set the callback. When the callback is already synchronized it doesn't make a lot of sense to go through qt's message system again (=>direct connection). Unless the callback needs to return very quickly and you want to do something big in your connected slot. If the callback is called asynchronously (in the threadcontext of the libraray) and you want to access GUI elements or something else that is not thread safe, you have to go for the Queued connection.

    Just try both options.. and see what works for you.. Or specify nothing and let qt decide. Qt decides upon matching thread contexts. Which should work just fine here.

    Cheers!

    Johannes
     

  • Join Date
    Nov 2007
    Location
    Italy
    Posts
    354
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: emit a signal from inside a callback routine

    Quote Originally Posted by JohannesMunk View Post
    Any. I suggest where you create the sounddata. If your sounddata is more generic than just data being played back, I suggest to set it up when you prepare it for playback. But then you will have to remove the connection after playback ended, to avoid multiple connections, when you play it back again. I don't know enough about the layout of your program to help you here..

    BTW: As the connect function is a static function of the QObject class, you only need to write "QObject::" in front of connect, if you are outside a QObject class.. Inside you can just write "connect(..)". But I showed you QObject::connect .. to underline that you can call this from everywhere.


    That depends on your callback library. Some execute the callback within the thread context of your application (synchronized) and some don't (async). Perhaps you can specify that when you set the callback. When the callback is already synchronized it doesn't make a lot of sense to go through qt's message system again (=>direct connection). Unless the callback needs to return very quickly and you want to do something big in your connected slot. If the callback is called asynchronously (in the threadcontext of the libraray) and you want to access GUI elements or something else that is not thread safe, you have to go for the Queued connection.

    Just try both options.. and see what works for you.. Or specify nothing and let qt decide. Qt decides upon matching thread contexts. Which should work just fine here.

    Cheers!

    Johannes
    The callback is executed when a playing file finish to play.
    In this case I have to stop a QTimer that I use to determine the "pcm position" within the
    audio data ( this to move a timeline ). So I think is not necesary to remove the connection. Because if a file is not playing the callback is never called. ( how I remove a callback?? ).

    I don't exactly know if the callback is sync or async, I have to ask to the fmod community for that.
    If is async I have to use the Queued connections flag right?

    Thank you
    Franco Amato
     

  • Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    238
    Thanks
    11
    Thanked 36 Times in 36 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: emit a signal from inside a callback routine

    You didn't get me.

    If you set up the signal slot connection whenever you START playing the sounddata on an Audiodevice there will be multiple signal-slot-connections, if you play the same sound multiple times and you don't remove the connection with QObject::disconnect after play back stopped.

    If you set it up only once when you create the sound everything is fine.

    Callback: No need to ask. Just try what works. You can't break anything.

    Good luck with your project!

    Johannes
     

  • Join Date
    Nov 2007
    Location
    Italy
    Posts
    354
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: emit a signal from inside a callback routine

    Quote Originally Posted by JohannesMunk View Post
    You didn't get me.

    If you set up the signal slot connection whenever you START playing the sounddata on an Audiodevice there will be multiple signal-slot-connections, if you play the same sound multiple times and you don't remove the connection with QObject::disconnect after play back stopped.

    If you set it up only once when you create the sound everything is fine.

    Callback: No need to ask. Just try what works. You can't break anything.

    Good luck with your project!

    Johannes
    Thank you very much Johannes for your precious help.

    Best Regards
    Franco Amato
     

  • Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    238
    Thanks
    11
    Thanked 36 Times in 36 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: emit a signal from inside a callback routine

    You are welcome!
  •  
    Join Date
    Nov 2007
    Location
    Italy
    Posts
    354
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: emit a signal from inside a callback routine

    Qt Ambassador Program
    Quote Originally Posted by JohannesMunk View Post
    You are welcome!
    Hi I have a new problem. Some posts ago you explained to me how to connect a signal to a slots of 2 "unknow" objects, eather one is part of the other.
    You gave to me this clear example:

    Qt Code:
    1. AudioDevice* ad = new AudioDevice();
    2. ...
    3. SoundData* sd = new SoundData();
    4. ...
    5. ::connect(ad,SIGNAL(soundStopped()),sd,SLOT(someSLOT()));
    To copy to clipboard, switch view to plain text mode 

    Supposing ad (or object A in general has a slider)
    I would connect the "valueChanged(int)" signal of the QSlider sl that's part of the object A with a slot that's part of the object B

    Something like this:

    Qt Code:
    1. AudioDevice* ad = new AudioDevice(); //ad has a QSlider sl
    2. ...
    3. SoundData* sd = new SoundData(); //sd has a slot slot_sd(int);
    4. ...
    5. ::connect(ad->sl,SIGNAL(valueChanged(int)),sd,SLOT(slot_sd(int)));
    To copy to clipboard, switch view to plain text mode 

    Is it possible?
    Best Regards
    Franco Amato
    阅读(1033) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~