使用OpenAL播放硬件设备采集的PCM音频数据
1.几个用到的结构体FRAMEINFO
typedef struct _FRAMEINFO
{
unsigned short codec_id; // Media codec type defined in sys_mmdef.h,
// MEDIA_CODEC_AUDIO_PCMLE16 for audio,双声道音频数据 PCM16LE:16代表采样位数为16bit,LE:Little Endian
//介绍PCM采样数据的网站: http://www.jianshu.com/p/43fd50f0a8ba
// MEDIA_CODEC_VIDEO_H264 for video.
unsigned char flags; // Combined with IPC_FRAME_xxx.
unsigned char cam_index; // 0 - n
unsigned char onlineNum; // number of client connected this device 连接到这个设备的客户端数量
unsigned char reserve1[3];
unsigned int reserve2; //
unsigned int timestamp; // Timestamp of the frame, in milliseconds 每一帧的时间戳,精确到毫秒级
// unsigned int videoWidth; 没有用到
// unsigned int videoHeight;也没有用到
}FRAMEINFO_t;
- (void)doRecvAudio
{
//NSLog(@"=== RecvAudio Thread Start (%@) ===", uid);
OpenALPlayer *player = nil;
BOOL bFirst = YES;
int readSize = 0;
char recvBuf[RECV_AUDIO_BUFFER_SIZE] = {0};
FRAMEINFO_t stFrmInfo = {0};
unsigned int nFrmNo = 0;
short decodeBuffer[640];
unsigned char outBuffer[1280];
if (sessionID >= 0 && avIndex >= 0)
{
avClientCleanAudioBuf(avIndex);
}
while(isRunningRecvAudioThread)
{
if (sessionID >= 0 && avIndex >= 0)
{
readSize = avRecvAudioData(avIndex, recvBuf, RECV_AUDIO_BUFFER_SIZE, (char *)&stFrmInfo, sizeof(FRAMEINFO_t), &nFrmNo);
if (readSize >= 0)
{
if (bFirst)
{
bFirst = NO;
player = [[OpenALPlayer alloc] init];
[player initOpenAL:AL_FORMAT_MONO16 :8000];
}
//printf("Receive Audio------------------------>>>%d %X:\n\n",readSize,stFrmInfo.codec_id);
//16进制0x8F 0x8A
if ((stFrmInfo.codec_id == 0x8F)||(stFrmInfo.codec_id == 0x8A))
{
memset(decodeBuffer, 0, sizeof(decodeBuffer));
G711Decoder(decodeBuffer,(unsigned char *)recvBuf,readSize,0);
memset(outBuffer, 0, sizeof(outBuffer));
memcpy(outBuffer, (unsigned char*)decodeBuffer, readSize*2);
//录音
[[Mp4VideoRecorder getInstance] writeListenData:(unsigned char*)outBuffer withSize:readSize*2];
[player openAudioFromQueue:outBuffer withLength:readSize*2];
}
}
else if (readSize == AV_ER_DATA_NOREADY) {
//NSLog(@"avRecvAudioData return AV_ER_DATA_NOREADY");
usleep(10 * 1000);
}
else if (readSize == AV_ER_LOSED_THIS_FRAME)
{
//NSLog(@"avRecvAudioData return AV_ER_LOSED_THIS_FRAME");
}
else
{
//NSLog(@"avRecvAudioData return err - %d", readSize);
usleep(10 * 1000);
}
}
else usleep(10 * 1000);
}
if (player != nil)
{
[player stopSound];
[player cleanUpOpenAL];
[player release];
player = nil;
}
NSLog(@"=== Recv Audio Thread Exit (%@) ===",self.name);
}