PDA

View Full Version : Problem emitting a signal



franco.amato
15th December 2009, 02:18
Hi to all,
in my application (an audio editor) I have a callback that emit a signal when a sound stop playing so:

//! Executed when a sound finish playing
FMOD_RESULT F_CALLBACK endCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type,
unsigned int commanddata1, unsigned int commanddata2)
{
(void)commanddata1; // Unused (to avoid warnings)
(void)commanddata2; // Unused (to avoid warnings)

SoundData* currentSound;

switch(type)
{
case FMOD_CHANNEL_CALLBACKTYPE_END:
{
FMOD_RESULT result;
FMOD::Channel *currentChannel = (FMOD::Channel *)channel;

void *ud = NULL;
result = currentChannel->getUserData( &ud );

/* inform that sound stopped */
emit AudioDevice::getInstance()->soundStopped();
break;
}
default:
break;
}

return FMOD_OK;
}
in the application I have 2 WaveWidgets ( waveform display ) having a slot connected to the signal emitted from the callback so:

/************************************************** **********************/
/* Constructor */
/************************************************** **********************/
WaveWidget::WaveWidget( QWidget* parent /* = 0 */ )
: QWidget( parent ),
m_wave( 0 ),
rb( 0 ),
m_CurrentTimePosition( 0 )
{
setFocusPolicy( Qt::TabFocus );
timer = new QTimer();

connect( timer, SIGNAL( timeout() ), this, SLOT( setCurrentTimePosition() ) );
connect( AudioDevice::getInstance(), SIGNAL( soundStopped() ), this, SLOT( stopTimer() ), Qt::QueuedConnection );
}

The stopTimer slot of the WaveWidget reset the timeLine to position 0 so:

/************************************************** **********************/
/* stopTimer */
/************************************************** **********************/
void WaveWidget::stopTimer()
{
timer->stop();
qDebug() << "Timer stopped";
resetTimeline();
}
and

/************************************************** **********************/
/* resetTimeline */
/************************************************** **********************/
void WaveWidget::resetTimeline()
{
int h = height();
QRect r = QRect( 0 , 0, m_CurrentTimePosition + 1, h );
// reset timeline
update( r );
// reset current value
m_CurrentTimePosition = 0;
// delete rubberband if one
if( rb )
{
delete rb;
rb = 0;
}
}
The problem is that when 1 of the 2 playing sounds stop playing ALL WaveWidget are informed of that and ALL reset their timeLine to 0 instead of only the right WaveWidget that efectively has its sound stopped.
How can I solve this problem?

I hope to get help.
Best Regards,
Franco

franco.amato
16th December 2009, 01:56
I solved it calling a method of the "userdata" object instead of emitting a signal so:


//! Executed when a sound finish playing
FMOD_RESULT F_CALLBACK endCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type,
unsigned int commanddata1, unsigned int commanddata2)
{
(void)commanddata1; // Unused (to avoid warnings)
(void)commanddata2; // Unused (to avoid warnings)

WaveWidget* wave;

switch(type)
{
case FMOD_CHANNEL_CALLBACKTYPE_END:
{
FMOD_RESULT result;
FMOD::Channel *currentChannel = (FMOD::Channel *)channel;

void *ud = NULL;
result = currentChannel->getUserData( &ud ); // Here I get the userdata

wave = (WaveWidget*)ud; // I cast it
wave->stopTimer(); // Call userdata method

//emit AudioDevice::getInstance()->soundStopped(); //inform that sound is stopped
break;
}
default:
break;
}

return FMOD_OK;
}

Bye