Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Next track and recurring callbacks (Read 5123 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Next track and recurring callbacks

Hi!

Just downloaded the Foobar2000 SDK to finally develop a plugin I have been thinking about develop for a long time. I got a Visual Studio project set up and have got the plugin DLL to load correctly in Foobar. I now got two problems to solve to have the basic functionality completed.

1. I need to be able to switch to next track in the playlist and change the volume. Is there some kind of global object I can use to do this? All I can find in the API is callback interfaces.

2. I need a callback interface class with a function that Foobar calls every update. Is there any class available for this?

Thanks for your helpfulness!

/Klarre

Next track and recurring callbacks

Reply #1
1. I need to be able to switch to next track in the playlist and change the volume. Is there some kind of global object I can use to do this? All I can find in the API is callback interfaces.
See playback_control. Example:
Code: [Select]
static_api_ptr_t<playback_control> pc;
pc->start(playback_control::track_command_next);
pc->set_volume(volume_in_db);


2. I need a callback interface class with a function that Foobar calls every update. Is there any class available for this?
Every update of what?

Have you seen the component tutorial on my site?

Next track and recurring callbacks

Reply #2
Thanks for the quick reply!

What I meant on the second question is that I want regular callbacks to a function in my component during the lifetime of Foobar. I guess I can solve this without Foobar by creating a threaded function, but it would be better if Foobar could give me these regular callbacks instead.

Next track and recurring callbacks

Reply #3
There is no such functionality in the SDK. You'll have to implement your own timer.

Next track and recurring callbacks

Reply #4
I solved it by creating a Windows thread that regularly adds a callback using the main_thread_callback_manager, which will call a function in my component regularly. I first tried to call playback_control::start directly within my own created Windows thread which made Foobar crash since this way is of course not thread safe.

Next track and recurring callbacks

Reply #5
You know, most people would just use SetTimer() from the main thread, for example in initquit::on_init(). I have a hard time imagining what you are trying to achieve.

Next track and recurring callbacks

Reply #6
Code: [Select]
class Thread : public main_thread_callback
{
public:
    virtual void callback_run()
    {
        // This function is being regularly called.
        // I use this function to poll data from an external input device
    }
};

class Timer
{
public:
    void start() { mThread = CreateThread(0, 0, &Timer::run, 0, 0, mThreadId); }
    void stop() { TerminateThread(mThread, 0); }

private:
    LPDWORD mThreadId;
    HANDLE mThread;

    static DWORD WINAPI run(void*)
    {
        while(true)
        {
            Sleep(1000); // Call interval of the callback_run function
            service_ptr_t<Thread> p_callback = new service_impl_t<Thread>();
            static_api_ptr_t<main_thread_callback_manager> man;
            man->add_callback(p_callback);
        }
    }
};

class Application : public initquit
{
public:
    virtual void on_init() { mTimer.start(); }
    virtual void on_quit() { mTimer.stop(); }

private:
    Timer mTimer;
};

static initquit_factory_t<Application> foo_initquit;


SetTimer might work. Havn't used that one so I'm not sure. But as you see in this stripped-down code I got a callback to callback_run each 1000 ms. Thats what I want, and it works great!

Next track and recurring callbacks

Reply #7
Thats what I want, and it accidentally works great as far as I know, and I don't!

There, fixed it for you.
Stay sane, exile.

Next track and recurring callbacks

Reply #8
So you mean its not safe, and that I am just a lucky boy who havn't got Foobar to crash during several minutes even when Sleep is very short?

Next track and recurring callbacks

Reply #9
My primary complaint is about TerminateThread, which just pulls the rug out of the executing code.
The thread may executing any of the statements in the thread function, and you have a very real risk of corrupting things or crashing hard, which you most likely do not want to do in such a critical place as application shutdown.
I strongly suggest that you follow the advice from foosion above and SetTimer in your init function and re-queue a timer every time your timer callback finishes.
If you're set on having a separate thread for some weird reason, at least use a synchronization primitive to notify the thread that it should break the loop in the thread procedure and join the thread before returning from on_quit.
Stay sane, exile.

Next track and recurring callbacks

Reply #10
I see. Thanks for pointing that out. Will consider the SetTimer approach since threads seems a little bit overkill for the purpose.