请教:ARM录音(wav)如何在PC(windows平台)上播放

jawiudi 2009-07-21 10:01:14
想用ARM(linux)实现录音,并通过网络将数据发送到PC(windows)上。
问题:
1、ARM读到的应该是纯音频数据,在PC端如何播放这个音频数据?
2、如果反过来,ARM如何播放PC传来的音频数据?

我的一点理解是,在音频数据上做些wave头文件的处理,就能播放了。但我想在内存中进行,不想存成文件。
希望高手指点一下,如何用VC或QT播放。
或者说说cat /dev/dsp >test.wav得到的wav文件与PC上的wav文件有什么不同。这样得到的文件我在PC上播放不了。
多谢!
...全文
548 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Behard 2009-07-24
  • 打赏
  • 举报
回复
哦 漏了定义
#define MAX_INQUEU 8
#define BUFSIZE 44100 // 22050 // 65536 // 1024

还有我的声音是从 10Hz 开始递增到 500Hz
Behard 2009-07-24
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 jawiudi 的回复:]
我就是这样做的,结果发送的如果WAV文件的数据,可以播放。纯数据就播放不了。代码如下:
waveOutOpen(&out,WAVE_MAPPER,&waveformat,
            0,0,CALLBACK_NULL);
waveOutPrepareHeader(out,hdr,sizeof(WAVEHDR));
waveOutWrite(out,hdr,sizeof(WAVEHDR));
[/Quote]

定义:

/* .h */
private: // User declarations
int m_CurOut;
bool m_blWaveOut;
HWAVEOUT hWaveOut;
WAVEFORMATEX waveFormOut;
PWAVEHDR pWaveOut[MAX_INQUEU];
char waveBufferOut[MAX_INQUEU][BUFSIZE];

public: // User declarations
__fastcall TfrmMain(TComponent* Owner);
virtual void __fastcall WndProc(Messages::TMessage &Message);


使用

/* .cpp */ /* 我使用 BCB,使用VC 的代码差不多 */
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <math.h>

#include "fmMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
//---------------------------------------------------------------------------
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
hWaveOut = NULL;
m_blWaveOut = false;
for(int i=0; i<MAX_INQUEU; i++)
pWaveOut[i] = (PWAVEHDR)new char[sizeof(WAVEHDR)];
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::ButtonStopClick(TObject *Sender)
{
int i;
if(NULL == hWaveOut) return;
if(m_blWaveOut) waveOutReset(hWaveOut);

for(i=0; i<MAX_INQUEU; i++)
{
waveOutUnprepareHeader(hWaveOut, pWaveOut[i], sizeof (WAVEHDR));
}
waveOutClose(hWaveOut);
hWaveOut = NULL;
m_blWaveOut = false;

ButtonPlay->Enabled = true;
ButtonStop->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::ButtonPlayClick(TObject *Sender)
{
ButtonStopClick(ButtonStop);

int i, j;
int miny, maxy, cycle;
int lasty, cury;
int freq[10] = {500, 1000};

for(i=1; i<10; i++) // for(i=1; i<ComboBoxFreq->Items->Count; i++)
freq[i] = freq[i-1]* 2;

// if(-1 == ComboBoxFreq->ItemIndex) ComboBoxFreq->ItemIndex = ComboBoxFreq->Items->Count- 1;
int step = BUFSIZE* MAX_INQUEU/ freq[0]; // [ComboBoxFreq->ItemIndex]; // 使用 500Hz
int counter = 0;
double ft = 0.0;
double ft_inc;
ft_inc = 2* 3.14159265389/ 4410; // 10Hz
for(i=0; i<MAX_INQUEU; i++)
{
for(j=0; j<BUFSIZE; j++)
{
waveBufferOut[i][j] = 128+ 127* sin(ft);
ft += ft_inc;
if(0 ==((++counter) % step))
{
ft_inc = (10+ 1.0*counter/step)* 2* 3.14159265389/ BUFSIZE;
}
}
}

waveFormOut.wFormatTag = WAVE_FORMAT_PCM;
waveFormOut.nChannels = 1;
waveFormOut.nSamplesPerSec = BUFSIZE;
waveFormOut.nAvgBytesPerSec = BUFSIZE;
waveFormOut.nBlockAlign = 1;
waveFormOut.wBitsPerSample = 8;
waveFormOut.cbSize = 0;

if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveFormOut, (DWORD)Handle, NULL, CALLBACK_WINDOW))
{
ShowMessage("waveOutOpen is failed!");
return;
}

for(i=0; i<MAX_INQUEU; i++)
{
if(NULL == pWaveOut[i]) continue;
pWaveOut[i]->lpData = waveBufferOut[i];
pWaveOut[i]->dwBufferLength = BUFSIZE;
pWaveOut[i]->dwBytesRecorded = 0;
pWaveOut[i]->dwUser = 0;
pWaveOut[i]->dwFlags = WHDR_BEGINLOOP;
pWaveOut[i]->dwLoops = 1;
pWaveOut[i]->lpNext = NULL;
pWaveOut[i]->reserved = 0;
}

m_CurOut = MAX_INQUEU- 1;
for(i=0; i<MAX_INQUEU-1; i++)
{
// Prepare and write
waveOutPrepareHeader(hWaveOut, pWaveOut[i], sizeof(WAVEHDR));
waveOutWrite(hWaveOut, pWaveOut[i], sizeof(WAVEHDR));
}

ButtonPlay->Enabled = false;
ButtonStop->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormDestroy(TObject *Sender)
{
for(int i=0; i<MAX_INQUEU; i++)
if(pWaveOut[i]) delete []pWaveOut[i];
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::WndProc(Messages::TMessage &Message)
{
switch(Message.Msg)
{
case MM_WOM_DONE: // 播放结束
waveOutUnprepareHeader((HWAVEOUT)Message.WParam, (PWAVEHDR)Message.LParam, sizeof(WAVEHDR));

waveOutPrepareHeader(hWaveOut, pWaveOut[m_CurOut], sizeof(WAVEHDR));
waveOutWrite(hWaveOut, pWaveOut[m_CurOut], sizeof(WAVEHDR));
if(++m_CurOut >= MAX_INQUEU) m_CurOut = 0;
break;
case MM_WOM_OPEN: // 打开输出设备
//StatusBar->Panels->Items[0]->Text = "正在输出";
m_blWaveOut = true;
break;
case MM_WOM_CLOSE:
//StatusBar->Panels->Items[0]->Text = "没有输出";
break;

case MM_WIM_OPEN: // 打开输入设备
//StatusBar->Panels->Items[1]->Text = "正在输入";
break;
case MM_WIM_CLOSE:
//StatusBar->Panels->Items[1]->Text = "没有输入";
break;
}
TForm::WndProc(Message);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
{
ButtonStopClick(ButtonStop);
}

jawiudi 2009-07-24
  • 打赏
  • 举报
回复
多谢楼上各位指点。
开始我说我播放不了,原因是我在PC上播放时的配置与ARM上录音的配置不同,修改后能播放了。

结帖!
ddcien 2009-07-23
  • 打赏
  • 举报
回复
cat /dev/dsp >test.wav

这个出来的test.wav是PCM数据,如果,平台间的PCM(DSP)设备设置相同的话,

cp test.wav /dev/dsp

就能播放了~~~
jawiudi 2009-07-22
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 behard 的回复:]
如果是纯数据的话,可以使用 waveOut 系列播放
waveOutOpen
waveOutPrepareHeader
waveOutWrite
等 API
[/Quote]
我就是这样做的,结果发送的如果WAV文件的数据,可以播放。纯数据就播放不了。代码如下:
waveOutOpen(&out,WAVE_MAPPER,&waveformat,
0,0,CALLBACK_NULL);
waveOutPrepareHeader(out,hdr,sizeof(WAVEHDR));
waveOutWrite(out,hdr,sizeof(WAVEHDR));
Behard 2009-07-22
  • 打赏
  • 举报
回复
如果是纯数据的话,可以使用 waveOut 系列播放
waveOutOpen
waveOutPrepareHeader
waveOutWrite
等 API
jawiudi 2009-07-22
  • 打赏
  • 举报
回复
有个疑问:我在arm上从声卡read一定大小的数据到buffer,然后传到PC上加wav头,比如hdr->lpData=buffer,(其中WAVEHDR hdr)。无法正常正常播放声音。
而我从正常的wav文件中read数据,按上述方法就能还播放。

我感觉从声卡读到的是纯音频数据,那从wav文件中读的难道和它不一样吗?难道包含了wav的头信息?

本来的想法是在ARM上不用做wav的转换,传到PC上再做,这个思路不对吗?
pottichu 2009-07-21
  • 打赏
  • 举报
回复
一般声卡录出来的是 pcm 格式的音频, 加上 wav 头应该就能播放了 。
找个linux下的录音程序看看就行。


cat /dev/dsp >test.wav 这样得到的根本不是音频文件,当然放不了。
ShowMan 2009-07-21
  • 打赏
  • 举报
回复
嗯,理解应该是正确的吧!
音频不熟。

起码FB是这个样子, 加上头就是BMP文件。
jawiudi 2009-07-21
  • 打赏
  • 举报
回复
多谢,试试。

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧