如何在默认音频输出设备中使用wav标头播放1个音频样本? [英] How to play 1 audio sample with the wav header in default audio output device?

查看:103
本文介绍了如何在默认音频输出设备中使用wav标头播放1个音频样本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在默认音频输出设备中使用wav标头播放1个音频样本?



使用directshow源过滤器的解决方案会很长时间,因为我需要自己编写源过滤器并将数据放入其中。



但是如果在c ++中有一个源过滤器的例子,我会接受它。



这就是为什么我想获得WinApi的方向。



更新:

我找到了这个例子directshow源过滤器在Samples\multimedia\directshow\filters\async中。



但它应该根据我的目的进行编辑。



任何人都可以在IStream中播放音频数据(文件)或在内存中播放音频数据(文件)的方式提供WinApi链接吗?



更新:

找到并修改CWave类。



现在我需要CWave类来同步播放文件。

有谁知道,怎么可能这样做?



UP日期:

我还需要根据WAV标头或基于AM_MEDIA_TYPE和WAVEFORMATEX(仅看到FORMAT_WaveFormatEx格式)计算当前块应播放的时间。

所以,我需要这个公式。

解决方案

我找到了CWave类并且为了自己的目的进行了修改。



CWave类可在 <链接中找到a href =http://www.codeproject.com/Articles/29676/CWave-A-Simple-C-Class-to-Manipulate-WAV-Files> CWave - 一个操作WAV文件的简单C ++类



似乎公式是

  if (local_work_time.GetSeconds()>= 1 
睡眠( 1 ) ;
else
{
HRESULT hr;

AM_MEDIA_TYPE mt;
ZeroMemory(& mt, sizeof (mt));

hr = local_main_dialog-> web_camera_dialog-> pAudioGrabber-> GetConnectedMediaType(& mt);

if (SUCCEEDED(hr))
{
if (mt.formattype==FORMAT_WaveFormatEx)
{
WAVEFORMATEX * wave_format_ex =(WAVEFORMATEX *)mt.pbFormat;

if (wave_format_ex!= NULL)
{
DWORD chunk_playing_time =
1000 *
wave_format_ex-> nAvgBytesPerSec /
wave_format_ex-> nSamplesPerSec /
wave_format_ex-> nChannels /
(wave_format_ex-> wBitsPerSample>> 3)/
(wave_format_ex-> nBlockAlign>> 1)
;

睡眠(chunk_playing_time);
}
}
_FreeMediaType(mt);
}
else
睡眠(1000 / CONST_AUDIO_PACKETS_PER_SECOND); // CONST_AUDIO_PACKETS_PER_SECONDкадроввсекунду
}





这是从netwotk获取流后的回放:

  //  Здесьвоспроизводитсяаудиосампле 
{
CWave local_wave;

local_wave.Load(received_microphone_stream);

/ * /
{
std :: fstream local_file;
local_file.open(c:\\temp\\file_received.wav,std :: ios_base :: out | std :: ios_base :: binary | std :: ios_base :: trunc);

char * local_file_data = new char [CONST_MESSAGE_LENGTH_IMAGE];

ULONG local_read_bytes = 0;

LARGE_INTEGER liBeggining = {0};

received_microphone_stream-> Seek(liBeggining,STREAM_SEEK_SET,NULL);

received_microphone_stream-> Read(local_file_data,CONST_MESSAGE_LENGTH_IMAGE,& local_read_bytes);

local_file.write(local_file_data,local_read_bytes);

delete [] local_file_data;

local_file.flush();

local_file.close();
}
// * /



ULARGE_INTEGER zero_size = { 0 ,< span class =code-digit> 0 };
received_microphone_stream-> SetSize(zero_size);

{
LARGE_INTEGER liBeggining = { 0 };

received_microphone_stream-> Seek(liBeggining,STREAM_SEEK_SET,NULL);
}

// local_wave.Save(Lc:\\\ \\ temp\\cwave_received.wav);
local_wave.Play();

{
// * /
< span class =code-keyword> if (local_wave.IsValid()== TRUE)
{
DWORD chunk_playing_time =
1000 *
local_wave.GetSize()/
local_wave.GetSampleRate()/
local_wave.GetChannels()/
(local_wave.GetBitsPerSample()>> 3);

睡眠(chunk_playing_time + 100);
}
// * /
}
}





接下来的改进将在等待玩工作线程的结束:

  //   in new thread  
local_wave.Play();

{
// * /
< span class =code-keyword> if (local_wave.IsValid()== TRUE)
{
DWORD chunk_playing_time =
1000 *
local_wave.GetSize()/
local_wave.GetSampleRate()/
local_wave.GetChannels()/
(local_wave.GetBitsPerSample()>> 3);

睡眠(chunk_playing_time + 100);
}
// * /
}


How to play 1 audio sample with the wav header in default audio output device?

Solution with directshow source filter will long time, because i need to write own source filter and put data to it.

But if there is an example of the source filter in c++ i will take it.

That is why i would like to get direction with WinApi.

UPDATE:
I have found the example of directshow source filter in "Samples\multimedia\directshow\filters\async".

But it should be edited for my purpose.

Can anybody give the WinApi link on the way to play audio data (file) in IStream or audio data (file) in the memory?

UPDATE:
CWave class is found and modified.

Now i need the CWave class to play the file synchronously.
Does any one know, how could be this done?

UPDATE:
Also i need to calculate the time current chunk should be playing based on WAV header or based on AM_MEDIA_TYPE and WAVEFORMATEX (seeing only the FORMAT_WaveFormatEx format).
So, i need the formula.

解决方案

I have found CWave class and modified if for own purposes.

CWave class is found on the link CWave - A Simple C++ Class to Manipulate WAV Files

It seems the formula is

if(local_work_time.GetSeconds()>=1)
					Sleep(1);
				else
				{
					HRESULT hr;

					AM_MEDIA_TYPE mt;
					ZeroMemory(&mt, sizeof(mt));

					hr = local_main_dialog->web_camera_dialog->pAudioGrabber->GetConnectedMediaType(&mt);

					if (SUCCEEDED(hr))
					{
						if(mt.formattype==FORMAT_WaveFormatEx)
						{
							WAVEFORMATEX *wave_format_ex = (WAVEFORMATEX *)mt.pbFormat;

							if(wave_format_ex!=NULL)
							{
								DWORD chunk_playing_time = 
									1000 *
									wave_format_ex->nAvgBytesPerSec/
									wave_format_ex->nSamplesPerSec/
									wave_format_ex->nChannels/
									(wave_format_ex->wBitsPerSample>>3)/
									(wave_format_ex->nBlockAlign>>1)
									;

								Sleep(chunk_playing_time);
							}
						}
						_FreeMediaType(mt);	
					}
					else
						Sleep(1000/CONST_AUDIO_PACKETS_PER_SECOND);		//	CONST_AUDIO_PACKETS_PER_SECOND кадров в секунду
				}



Here is the playback after getting th stream from the netwotk:

//	Здесь воспроизводится аудио сампле
		{
			CWave local_wave;

			local_wave.Load(received_microphone_stream);

			/*/
			{
			std::fstream local_file;
			local_file.open("c:\\temp\\file_received.wav",std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);

			char *local_file_data = new char[CONST_MESSAGE_LENGTH_IMAGE];

			ULONG local_read_bytes = 0;

			LARGE_INTEGER liBeggining = { 0 };

			received_microphone_stream->Seek(liBeggining, STREAM_SEEK_SET, NULL);

			received_microphone_stream->Read(local_file_data,CONST_MESSAGE_LENGTH_IMAGE,&local_read_bytes);

			local_file.write(local_file_data, local_read_bytes);

			delete [] local_file_data;

			local_file.flush();

			local_file.close();
			}
			//*/


			ULARGE_INTEGER zero_size = {0,0};
			received_microphone_stream->SetSize(zero_size);

			{
				LARGE_INTEGER liBeggining = { 0 };

				received_microphone_stream->Seek(liBeggining, STREAM_SEEK_SET, NULL);
			}

			//local_wave.Save(L"c:\\temp\\cwave_received.wav");
			local_wave.Play();

			{
				//*/
				if(local_wave.IsValid()==TRUE)
				{
					DWORD chunk_playing_time = 
						1000 *
						local_wave.GetSize()/
						local_wave.GetSampleRate()/
						local_wave.GetChannels()/
						(local_wave.GetBitsPerSample()>>3);

						Sleep(chunk_playing_time+100);
				}
				//*/
			}
		}



Next improvement will be playing and waiting for end of playing in worker thread:

// in new thread
local_wave.Play();

			{
				//*/
				if(local_wave.IsValid()==TRUE)
				{
					DWORD chunk_playing_time = 
						1000 *
						local_wave.GetSize()/
						local_wave.GetSampleRate()/
						local_wave.GetChannels()/
						(local_wave.GetBitsPerSample()>>3);

						Sleep(chunk_playing_time+100);
				}
				//*/
			}


这篇关于如何在默认音频输出设备中使用wav标头播放1个音频样本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆