我有一连串的WAV文件列表(数字或汉字发音),我希望一个一个次序的将它们播放出来。但现在默认DirectSound上播放过程是异步的,就是说我的声音放入以后是在一个瞬间同时开始播放现在想请问一下,我如何才能使这些声音同步,次序的播放出来?最好能给出范例。分数我后面会再加的,谢谢了。

解决方案 »

  1.   

    多买几个音响,同时奏交响乐.Hoho
      

  2.   

    楼主的意思就是"顺序播放"吗?如果是这样的话,
    在timer控件中判断播放文件的状态是否为stopped,如果是载入并播放下一首就可以了.
      

  3.   


    楼上的方法不错。我也曾想过,但问题是我现在没办法判断特定文件播放的结束,设备只有一个,但我始终有个背景音乐在播放。如果无法进行区别的话,那么播放状态就不会转变为Stopped的。
      

  4.   


            protected override void WndProc(ref   Message m)
            {
              
                if (m.Msg == WM_GRAPHNOTIFY)
                {
                    int lEventCode;
                    int lParam1, lParam2;                while (true)
                    {
                        try
                        {
                            m_objMediaEventEx.GetEvent(out lEventCode,
                                out lParam1,
                                out lParam2,
                                0);                        m_objMediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2);                        if (lEventCode == EC_COMPLETE)//这里就是检测是否播放完.我这里代码是播放完,什么也不做,你可以让它在播放下一首,你用的是quartz吧?
                            {
                                m_objMediaControl.Stop();
                                m_objMediaPosition.CurrentPosition = 0;
                                m_CurrentStatus = MediaStatus.Stopped;
                                UpdateStatusBar();
                                UpdateToolBar();
                            }
                        }
                        catch (Exception)
                        {
                            break;
                        }
                    }
                }
                base.WndProc(ref   m);
            }        
      

  5.   

    m_objMediaEventEx.GetEvent(out lEventCode,
                                out lParam1,
                                out lParam2,
                                0);
    就是这个时间啊.
      

  6.   


    代码能给份完整的吗?你只写出事件这一块,我看不出运行的机制啊。包括m_objMediaEventEx这个对象是从哪儿来的
      

  7.   


    using QuartzTypeLib;
        public partial class Form1 : Form
        {
            private const int WM_APP = 0x8000;
            private const int WM_GRAPHNOTIFY = WM_APP + 1;
            private const int EC_COMPLETE = 0x01;
            private const int WS_CHILD = 0x40000000;
            private const int WS_CLIPCHILDREN = 0x2000000;
            enum MediaStatus
            {
                None,
                Stopped,
                Paused,
                Running
            }
            private FilgraphManager m_objFilterGraph = null;
            private IBasicAudio m_objBasicAudio = null;
            private IVideoWindow m_objVideoWindow = null;
            private IMediaEvent m_objMediaEvent = null;
            private IMediaEventEx m_objMediaEventEx = null;
            private IMediaPosition m_objMediaPosition = null;
            private IMediaControl m_objMediaControl = null;
            private MediaStatus m_CurrentStatus = MediaStatus.None;
            public Form1()
            {
                InitializeComponent();
                UpdateStatusBar();
                UpdateToolBar();
                timer1.Enabled = true;            
            }
            protected override void WndProc(ref   Message m)
            {          
                if (m.Msg == WM_GRAPHNOTIFY)
                {
                    int lEventCode;
                    int lParam1, lParam2;
                    while (true)
                    {
                        try
                        {
                            m_objMediaEventEx.GetEvent(out lEventCode,
                                out lParam1,
                                out lParam2,
                                0);                        m_objMediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2);                        if (lEventCode == EC_COMPLETE)
                            {
                                m_objMediaControl.Stop();
                                m_objMediaPosition.CurrentPosition = 0;
                                m_CurrentStatus = MediaStatus.Stopped;
                                UpdateStatusBar();
                                UpdateToolBar();
                            }
                        }
                        catch (Exception)
                        {
                            break;
                        }
                    }
                }
                base.WndProc(ref   m);
            }
            private void openToolStripMenuItem_Click(object sender, EventArgs e)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();            openFileDialog.Filter = "Media Files|*.mpg;*.avi;*.wma;*.mov;*.wav;*.mp2;*.mp3|All Files|*.*";
                if (DialogResult.OK == openFileDialog.ShowDialog())
                {
                    // CleanUp();
                    m_objFilterGraph = new FilgraphManager();
                    m_objFilterGraph.RenderFile(openFileDialog.FileName);
                    m_objBasicAudio = m_objFilterGraph as IBasicAudio;
                    try
                    {
                        m_objVideoWindow = m_objFilterGraph as IVideoWindow;
                        m_objVideoWindow.Owner = (int)panel1.Handle;
                        m_objVideoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN;
                        m_objVideoWindow.SetWindowPosition(panel1.ClientRectangle.Left,
                            panel1.ClientRectangle.Top,
                            panel1.ClientRectangle.Width,
                            panel1.ClientRectangle.Height);
                    }
                    catch (Exception)
                    {
                        m_objVideoWindow = null;
                    }
                    m_objMediaEvent = m_objFilterGraph as IMediaEvent;
                    m_objMediaEventEx = m_objFilterGraph as IMediaEventEx;
                    m_objMediaEventEx.SetNotifyWindow((int)this.Handle, WM_GRAPHNOTIFY, 0);
                    m_objMediaPosition = m_objFilterGraph as IMediaPosition;
                    m_objMediaControl = m_objFilterGraph as IMediaControl;
                    this.Text = "mediaPlayer - [" + openFileDialog.FileName + "]";
                    m_objMediaControl.Run();
                    m_CurrentStatus = MediaStatus.Running;
                   this .Text = m_objBasicAudio.Volume .ToString ()+m_objMediaPosition .Rate .ToString ();
                   m_objMediaPosition.Rate = 1.0;
                  // m_objBasicAudio.Volume = 2;
                    UpdateStatusBar();
                    UpdateToolBar();
                }
            }
            private void CleanUp()
            {
                if (m_objMediaControl != null)
                    m_objMediaControl.Stop();
                m_CurrentStatus = MediaStatus.Stopped;
                if (m_objMediaEventEx != null)
                    m_objMediaEventEx.SetNotifyWindow(0, 0, 0);
                if (m_objVideoWindow != null)
                {
                    m_objVideoWindow.Visible = 0;
                    m_objVideoWindow.Owner = 0;
                }
                if (m_objMediaControl != null) m_objMediaControl = null;
                if (m_objMediaPosition != null) m_objMediaPosition = null;
                if (m_objMediaEventEx != null) m_objMediaEventEx = null;
                if (m_objMediaEvent != null) m_objMediaEvent = null;
                if (m_objVideoWindow != null) m_objVideoWindow = null;
                if (m_objBasicAudio != null) m_objBasicAudio = null;
                if (m_objFilterGraph != null) m_objFilterGraph = null;
            }
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (m_CurrentStatus == MediaStatus.Running)
                {
                    UpdateStatusBar();
                }
            }
            private void toolBar_Click(object sender, EventArgs e)
            {
                ToolStripItem item = toolBar.GetItemAt(MousePosition.X - this.Location.X, 1);
                if (item != null && item.Enabled == true)
                {
                    switch (toolBar.Items.IndexOf(item))
                    {
                        case 0:
                            m_objMediaControl.Run();
                            m_CurrentStatus = MediaStatus.Running;
                            break;
                        case 2:
                            m_objMediaControl.Pause();
                            m_CurrentStatus = MediaStatus.Paused;
                            break;
                        case 4:
                            m_objMediaControl.Stop();
                            m_objMediaPosition.CurrentPosition = 0;
                            m_CurrentStatus = MediaStatus.Stopped;
                            break;
                    }
                    UpdateStatusBar();
                    UpdateToolBar();
                }
            }
            private void exitToolStripMenuItem_Click(object sender, EventArgs e)
            {
                this.Close();
                Application.Exit();
            }        
        }
      

  8.   


            private void UpdateStatusBar()
            {
                switch (m_CurrentStatus)
                {
                    case MediaStatus.None: statuslab1.Text = "Stopped"; break;
                    case MediaStatus.Paused: statuslab1.Text = "Paused "; break;
                    case MediaStatus.Running: statuslab1.Text = "Running"; break;
                    case MediaStatus.Stopped: statuslab1.Text = "Stopped"; break;
                }
                if (m_objMediaPosition != null)
                {
                    int s = (int)m_objMediaPosition.Duration;
                    int h = s / 3600;
                    int m = (s - (h * 3600)) / 60;
                    s = s - (h * 3600 + m * 60);
                    statuslab2.Text = String.Format("{0:D2}:{1:D2}:{2:D2}", h, m, s);
                    s = (int)m_objMediaPosition.CurrentPosition;
                    h = s / 3600;
                    m = (s - (h * 3600)) / 60;
                    s = s - (h * 3600 + m * 60);
                    statuslab3.Text = String.Format("{0:D2}:{1:D2}:{2:D2}", h, m, s);
                }
                else
                {
                    statuslab2.Text = "00:00:00";
                    statuslab3.Text = "00:00:00";
                }
            }
            private void UpdateToolBar()
            {
                switch (m_CurrentStatus)
                {
                    case MediaStatus.None: toolBarButton1.Enabled = false;
                        toolBarButton2.Enabled = false;
                        toolBarButton3.Enabled = false;
                        break;                case MediaStatus.Paused: toolBarButton1.Enabled = true;
                        toolBarButton2.Enabled = false;
                        toolBarButton3.Enabled = true;
                        break;                case MediaStatus.Running: toolBarButton1.Enabled = false;
                        toolBarButton2.Enabled = true;
                        toolBarButton3.Enabled = true;
                        break;                case MediaStatus.Stopped: toolBarButton1.Enabled = true;
                        toolBarButton2.Enabled = false;
                        toolBarButton3.Enabled = false;
                        break;
                }
            }
      

  9.   


    baihe_591,不解决问题啊。您在代码中引用的QuartzTypeLib是否为托管环境下的DLL?包含在项目中是否可以直接使用了呢?(我找了几台电脑,都没你所说的这个库文件)因为现在系统已经要安装.Net2.0框架和DirectX平台了,所以我不想再加多外部的引用。能否直接使用DirectSound来实现这个功能?这个帖子我已经加过分了,不能再加了。如果谁能帮我解决(直接使用DirectSound实现)再加200分,另开帖给。谢谢大家了。
      

  10.   


    先说下我自己的想法,有两种。一种是使用事件,这个也是最简单方便的解决方案,基本两三句话就解决了。就是找到播放结束的事件,然后在事件的句柄上加入播放第二段声音的事件。另一种就是使用流,将文件分段读入,然后传送给DirectSound,在第一个文件读完后,继续读第二个文件以上是我的想法,不过不幸的事,两种方法我都没找到好的范例。有哪位能帮帮我,多谢了。
      

  11.   


    奖励分数帖:
    http://topic.csdn.net/u/20080903/09/15b69472-b644-4db5-b655-30d06a77083e.html
      

  12.   

    在程序项目中添加"[WindowsDir]\system32\quartz.dll"引用.
      

  13.   

    也可以用Mcisendstring API来播放文件.
    你还是加我QQ吧 ,284238731
      

  14.   


    分数加好了,提供解决方案的在本帖回复,到另一个帖留名接分即可。http://topic.csdn.net/u/20080903/09/15b69472-b644-4db5-b655-30d06a77083e.html 
      

  15.   

    我已经按你的要求做了一个实例,下载地址:http://download.csdn.net/source/604411窗体有一个button和listbox,程序运行后点button添加音频文件,文件被加入到listbox中,此时会自动循环播放listbox中的文件.
      

  16.   


    楼上的范例我看了,但你的方案中没办法实现异步的播放啊。谁有直接用DirectSound实现的方案?多谢了。
      

  17.   


    再加分了,600分,请大家帮助解决,谢谢。http://topic.csdn.net/u/20080910/14/d8a92641-e39e-452e-810d-af8681662188.html
      

  18.   

    LZ ,异步和同步有什么区别?我的代码为什么不是异步的?那dirctsound该怎么用异步?
      

  19.   

    用GetFiles()遍历所有文件 如果文件格式符合
    然后如果为wav文件 就发声就好了 
      

  20.   

     就是让他一个个的读字吧:(我证实可行)
     
     http://www.techrss.cn/html/2007/05-15/13555.htm