🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.multimedia
5 messages
5 total messages Started by Isaac Tue, 27 May 2008 13:57
CALLBACK_THREAD
#198
Author: Isaac
Date: Tue, 27 May 2008 13:57
46 lines
2002 bytes
Hi,

I'm experimenting with digital audio (hobby of mine).
I can play/record with code made for a single executable
application using CALLBACK_WINDOW and message maps.
Absolutely no problems there.

I'd like to write up a self-contained separate thread for
playback (and another one for record) -- no calling of other
threads etc -- everything in the one playback/record thread,
however, I can't seem to make the following code work.

In the implementation file I have:

	waveOutOpen(&WaveHandle,
                    WAVE_MAPPER,
                    &WaveFormat,
                    (double)ThreadID,
                    (double)this,
                    CALLBACK_THREAD)

	.......

and the following in the header file:

	BEGIN_MESSAGE_MAP
	   MESSAGE_HANDLER(MM_WOM_DONE, TMessage, OnWaveMessage)
	END_MESSAGE_MAP(TThread)


Also tried the following with no joy.

	BEGIN_MESSAGE_MAP
	   MESSAGE_HANDLER(WOM_DONE, TMessage, OnWaveMessage)
	END_MESSAGE_MAP(LineOut)


It plays (or records) OK, but it's like messages aren't being handled.
OnWaveMessage doesn't get called at all.

What am I missing?

Thanks in advance for any assistance.

Isaac
Re: CALLBACK_THREAD
#199
Author: Remy Lebeau (TeamB)
Date: Tue, 27 May 2008 20:39
15 lines
1606 bytes
"Isaac" <f4ier@hotmail.com> wrote in message 
news:483c134e$1@newsgroups.borland.com...

> It plays (or records) OK, but it's like messages aren't being handled.

You are trying to catch the messages as if they are being sent to a specific 
HWND, but they are actually being posted to the specified ThreadID's message 
queue instead (presumably the main thread, as you did not show which 
ThreadID you are actually passing to waveOutOpen()).  As such, you will have 
to use the TApplication::OnMessage event in order to handle messages that 
are posted to the main thread message queue.


Gambit 
Re: CALLBACK_THREAD
#200
Author: Isaac
Date: Wed, 28 May 2008 03:53
71 lines
2890 bytes
Hi, thanks for your prompt reply.

I've three units.

Unit1:  the main application
Unit2:  playback thread (which uses the code tidbits above)
Unit3:  record thread

I thought that it may not be as simple as putting ThreadID in
the parameters of waveOutOpen; that by doing so the messages
were actually being sent to the main application instead.

So I wrote a function that sets the thread ID to test this
(but no joy as well).

   Unit1.cpp ===================================================
      __fastcall TForm1::TForm1(TComponent* Owner)
                        : TForm(Owner) {
         playWave = new LineOut(false);
         playWave->SetThreadID(playWave->ThreadID);
         ...
         ..
         .
      }

   Unit2.cpp ===================================================
      void __fastcall LineOut::SetThreadID(int temp) {
         myThreadID = temp;
      }
      ----------------------------------------------------------
      __fastcall LineOut::LineOut(bool CreateSuspended)
                         : TThread(CreateSuspended) {
         ...
         ..
         .
         waveOutOpen(&WaveHandle,
                     WAVE_MAPPER,
                     &WaveFormat,
                     (double)myThreadID,
                     (double)this,
                     CALLBACK_THREAD)

         ...
         ..
         .
      }
      ----------------------------------------------------------
      void __fastcall LineOut::OnWaveMessage(TMessage &msg) {
         if(msg.Msg == MM_WOM_DONE) {
           // Do something
         }
      }

   Unit2.h =====================================================
      public:
         BEGIN_MESSAGE_MAP
            MESSAGE_HANDLER(WOM_DONE, TMessage, OnWaveMessage)
         END_MESSAGE_MAP(TThread)


WOM_DONE or MM_WOM_DONE are still not being handled.

Is there something about threads and messages that I should
read about?  I searched the net for some clue from a similar
setup to mine with zero success.


I'll lookup TApplication::OnMessage, thanks!

Isaac
Re: CALLBACK_THREAD
#201
Author: Remy Lebeau (TeamB)
Date: Wed, 28 May 2008 20:08
97 lines
4014 bytes
"Isaac" <nospam@nospam.com> wrote in message 
news:483cd729$1@newsgroups.borland.com...

> I thought that it may not be as simple as putting ThreadID
> in the parameters of waveOutOpen; that by doing so the
> messages were actually being sent to the main application
> instead.

In the code you have shown now, you are not sending the messages to the main 
thread at all.  So the TForm (or TApplication) cannot process the messages 
because they will never see them.

> So I wrote a function that sets the thread ID to test this
> (but no joy as well).

Your code is wrong for that.  It is calling waveOutOpen() in the thread 
constructor before the myThreadID variable has a chance of being assigned 
any value.  Since you are using the thread's ThreadID property anyway, your 
myThreadID variable is redundant.  You are also calling waveOutOpen() before 
the thread's message queue is even created.

>         BEGIN_MESSAGE_MAP
>            MESSAGE_HANDLER(WOM_DONE, TMessage, OnWaveMessage)
>         END_MESSAGE_MAP(TThread)

You can't use a message map with a TThread.  You will have to code the 
message pump manually by calling Get/PeekMessage(), TranslateMessage(), and 
DispatchMessage() directly.  For example:


    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
        playWave = new LineOut(false);
        ...
    }


    __fastcall LineOut::LineOut(bool CreateSuspended)
        : TThread(CreateSuspended)
    {
        ...
    }

    void __fastcall LineOut::Execute()
    {
        HWAVEOUT WaveHandle
        MSG msg;

        // create message queue
        PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);

        waveOutOpen(
            &WaveHandle,
            WAVE_MAPPER,
            &WaveFormat,
            this->ThreadID,
            (DWORD) this,
            CALLBACK_THREAD);

        while( !Terminated )
        {
            if( MsgWaitForMultipleObjects(0, NULL, FALSE, 1000, QS_ALLINPUT) 
== WAIT_OBJECT_0 )
            {
                while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
                {
                    switch( msg.message )
                    {
                        case MM_WOM_DONE:
                        {
                            //...
                            break;
                        }
                        //...
                        default:
                        {
                            TranslateMessage(&msg);
                            DispatchMessage(&msg);
                            break;
                        }
                    }
                }
            }
        }

        waveOutClose(WaveHandle);
    }

> I'll lookup TApplication::OnMessage, thanks!

That will only work if you use the global MainThreadID as the ThreadID 
passed to waveOutOpen().


Gambit 
Re: CALLBACK_THREAD
#203
Author: Isaac
Date: Wed, 04 Jun 2008 07:41
8 lines
1226 bytes
Thanks for your suggestion in using TApplication::OnMessage()!  I managed to write a working set of playback/sampling code.  And yes -- I did need to pass the main thread ID to waveOutOpen() to process messages.

Also, thanks for the heads-up and sample code (!!) about TThread and messages.  I'll be playing around with CALLBACK_EVENT next.

Cheers!

Isaac
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads