Solved

Wave File

Posted on 2003-12-11
16
395 Views
Last Modified: 2013-11-20
Hi,
I have used PlaySound function,and i need to know when the wave file stop playing, in order to do some action while it's playing.
I used :
PlaySound(pszSound, NULL, SND_ASYNC | SND_FILENAME);
Then i have :
while( IsPlaying() )//somthing like that.
   {
     ...      

   }
How can i know if the wave file is still playing and when it stops?

Thanks a lot.

Dani.
0
Comment
Question by:dani333
  • 8
  • 5
  • 3
16 Comments
 
LVL 6

Expert Comment

by:GloomyFriar
ID: 9922363
SND_SYNC - Synchronous playback of a sound event. PlaySound returns after the sound event completes.
0
 
LVL 6

Expert Comment

by:GloomyFriar
ID: 9922393
You can run the PlaySound() with the  SND_SYNC flag in a separate thread.
And then you can use WaitForSingleObject to define is the thread still running(playing) or not.
0
 

Author Comment

by:dani333
ID: 9922436
How can i use SND_SYNC?
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9922455
if (PlaySound(0, NULL, SND_ASYNC | SND_NOSTOP | SND_NODEFAULT))
    // Sound complete
else
    // Sound still playing.

Hope this helps.
0
 

Author Comment

by:dani333
ID: 9922845
It doesn't work:-(
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9923515
Hmm, odd.  Does the request reset the sound device?

If you know the length of the sound file you could use waveOutGetPosition or the waveOutProc to catch the callback when if finishes.  I'm not sure if the callback will get called for PlaySound, though.  It is considered a wave library function, so it might get the WOM_DONE message.

Of course, the solution GloomyFriar offered of doing a synchronous playback in another thread might be  simpler solution.

Hope this helps.
0
 

Author Comment

by:dani333
ID: 9923699
I don't know how to use WaitForSingleObject() function and i'm not so good with threads
Can u help me with that please?

Thanks.
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9924123
Well, personally I don't think you want to use WaitForSingleObject simply because you don't want to wait, you want to process during playback or you would have used SND_SYNC.

The easiest way to do the threading is in the object that plays the sound, be it a dialog, window, or whatever.  I'll pretend it is CSoundObject.  First add the following members:

class CSoundObject
{
  ...
public:
    void StartSound(const CString& strSoundName);
    void PlayTheSound();

private:
    CString m_strSound;
    bool m_bPlaying;
    CCriticalSection m_cPlayCritical;

    static void CallPlay(void *pData);
};


Then write the functions as

bool CSoundObject::StartSound(const CString& strSoundName)
{
    m_cPlayCritical.Lock();
    if (!m_bPlaying)
    {
        m_cPlayCritical.Unlock();
        m_strSound = strSoundName
        m_bPlaying = true;
        _beginthread(CallPlay, 0, (void*)(this));
    }
    else
        m_cPlayCritical.Unlock();

    return m_bPlaying;
}

void CSoundObject::CallPlay(void *pData)
{
     ((CSoundObject*)pData)->PlayTheSound();
    _endthread();
}

void CSoundObject::PlayTheSound()
{
    m_cPlayCritical.Lock();
    if (!m_bPlaying)
    {
        m_cPlayCritical.Unlock();
        PlaySound(m_strSound, NULL, SND_SYNC);
        m_cPlayCritical.Lock();
        m_bPlaying = false;
    }
    m_cPlayCritical.Unlock();
}


Then just call StartSound with the name of your sound and check m_bPlaying to see if the thread is still active.  Be sure to put checks in a critical section, though I'm not sure it makes a difference for something like checking a bool, it never hurts.

Hope this helps.

0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:dani333
ID: 9925098
Ok,I will check it tomorrow, hope it will work and you will get
my points.

0
 
LVL 6

Expert Comment

by:GloomyFriar
ID: 9927227
>and you will get my points.
Don't forget, it's my idea.
0
 

Author Comment

by:dani333
ID: 9934727
Hi again,
I did what u told me with the thread and stuff but i still can't do other operation while the wave file is playing.
I want to do it in the function OnInitDialog() ,the program is stuck in the StartSound line
until the wave file is finished,so what should i do,where should i check the flag?

Thanks again.
0
 

Author Comment

by:dani333
ID: 9935815
Help me with that please...
0
 
LVL 6

Accepted Solution

by:
GloomyFriar earned 300 total points
ID: 9937362
The working code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

class KPlayer
{
public:
   KPlayer(char *FileName);
   BOOL IsPlaing(void);

private:
   HANDLE m_hThread;
   DWORD m_idThread;
   char m_FileName[_MAX_PATH + 1];
   static DWORD WINAPI PlayThreadFunc(LPVOID lpParameter);
};

KPlayer::KPlayer(char *FileName)
{
  strcpy(m_FileName, FileName);
  m_hThread = CreateThread(NULL, 0, PlayThreadFunc, this, 0, &m_idThread);
  if (NULL == m_hThread)
  {
    printf("ERROR: Can't create thread [%d]", GetLastError());
  }
}

BOOL KPlayer::IsPlaing(void)
{
  if (WAIT_TIMEOUT == WaitForSingleObject(m_hThread, 0))
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}

DWORD WINAPI KPlayer::PlayThreadFunc(LPVOID lpParameter)
{
  KPlayer *pPlayerObj = (KPlayer *)lpParameter;
  PlaySound(pPlayerObj->m_FileName, NULL, SND_SYNC);
  return 0;
}

int main(int argc, char **argv)
{
  if (argc < 2)
  {
    printf("\nUsage: %s FileName\n", argv[0]);
    exit(-1);
  }

  KPlayer player(argv[1]);

  for (int i=0; i<1000; i++)
  {
    if (player.IsPlaing())
    {
      printf("Still playing...\n");
    }
    else
    {
      printf("Play stopped.\n");
    }
   
    Sleep(15);
  }

  return 0;
}
0
 

Author Comment

by:dani333
ID: 9937513
Hi GloomyFriar,
Sorry to disturb you again hope u will understand my problem now.
This is what i have made:

BOOL CPlayerDlg::OnInitDialog()
{
      CDialog::OnInitDialog();

 .
 .
 .
       

    PlayStartSound(".\\wav\\start1.wav");

return TRUE;  
}
 How can I check if IsPlaying() automaticly after the OnInitDialog() finished and already start
playing?
I don't have main or somthing,the wave file start playing in the OnInitDialog(), i can't do the for loop in this function it won't work,where can i put it ?

Thanks again.
0
 
LVL 6

Expert Comment

by:GloomyFriar
ID: 9940811
I can't understand what you want to make.
You can use player.IsPlaing() anywhere in you programm.
One hint. Create the player like this:
KPlayer *pPlayer(FileName);
and don't forget to destroy it like this:
delete pPlayer.

One addition to the code:
KPlayer::~KPlayer(void)
{
  if (WAIT_OBJECT_0 != WaitForSingleObject(m_hThread, 0))
  {
    TerminateThread(m_hThread, -1);
  }
}

Do you want to know, when the playing stopped?
Then you can do like the following:
DWORD WINAPI KPlayer::PlayThreadFunc(LPVOID lpParameter)
{
  KPlayer *pPlayerObj = (KPlayer *)lpParameter;
  PlaySound(pPlayerObj->m_FileName, NULL, SND_SYNC);

  /*
   * You can use PostThreadMessage, if you want.
   * To get window handle you can use AfxGetMainWnd( );
   * or just pass it to KPlayer constructor like this:
   * KPlayer::KPlayer(char *FileName, HWND hWnd);
   * {
   *   ...
   *   m_hWnd = hWnd;
   * }
   */
  PostMessage(m_hWnd, WM_USER + 100, 0, 0);
  return 0;
}
0
 

Author Comment

by:dani333
ID: 9941246
I put PlayStartSound() in the constructor and IsPlaying in OnPaint().

Thanks for your help.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Adapt this command to show who installed 29 102
iSeries FTP Exit Program 8 114
conditional code and condition difference 9 65
only14 challenge 19 64
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now