mpg123:error: Invalid UTF16 surrogate pair at 20 (0xff08).

dudujerry 2018-08-17 08:25:46
今天试用了mpg123,看了各种教程,但是放到类里无法播放,于是直接试了一下输出错误信息,百度找不到是什么,但是好像0xff08对应的是“(”
项目也试过调整Unicode,但是没用 (20行是DSBUFFERDESC dsbd; )
//复制的控制台代码,不能用
#include <iostream>
using namespace std;
#include <windows.h>
#include "mpg123.h"
#include <dsound.h>

#pragma comment (lib,"dsound.lib")
#pragma comment (lib,"./libmpg123.lib")


BYTE *buffer;
int err = MPG123_OK; //mpg123的工作状态
long rate = 0;
bool hasFile = false;
int channels = 0, enc = 0;
mpg123_handle *mh = NULL;

LPDIRECTSOUND g_pD3DSound = NULL; //DirectSound的设备指针
LPDIRECTSOUNDBUFFER g_pD3DSoundBuffer = NULL; //指向音乐数据缓存的指针
DSBUFFERDESC dsbd; //音乐数据的缓存格式
WAVEFORMATEX waveform; //当前mp3的音乐格式
HWND hwnd = CreateWindowA("Button", "aaa", 0, 0, 0, 0, 0, 0, 0, 0, 0);//一定要创建一个窗口句柄,不然没办法播放

void D3DInit(long n)
{
DirectSoundCreate(NULL, &g_pD3DSound, NULL); //创建播放设备
g_pD3DSound->SetCooperativeLevel(hwnd, DSSCL_NORMAL); //设定协同等级,就是缓存的写入级别
memset(&dsbd, 0, sizeof(dsbd));
dsbd.dwSize = sizeof(dsbd);
dsbd.dwFlags = DSBCAPS_GLOBALFOCUS; //这么设置保证在后台也能播放
dsbd.dwBufferBytes = n; //解码后的数据大小,以字节计算
dsbd.lpwfxFormat = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX));
}

void CleanUp()
{
//一些清理工作,顺序不要颠倒
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();

//此处顺序也不能乱
if (g_pD3DSoundBuffer) { g_pD3DSoundBuffer->Release(); g_pD3DSoundBuffer = NULL; };
if (g_pD3DSound) { g_pD3DSound->Release(); g_pD3DSound = NULL; };
}

void Open(CHAR* FileName)
{
//mpg123初始化
mpg123_init();
mh = mpg123_new(NULL, &err);

//检测格式是否正确
mpg123_open(mh, FileName);
//获得每秒采样率,声道数,以及编码格式
mpg123_getformat(mh, &rate, &channels, &enc);
//mpg123只支持这两种MP3编码格式,已经够了,大部分就是这样的
if (enc != MPG123_ENC_SIGNED_16 && enc != MPG123_ENC_FLOAT_32)
{
fprintf(stderr, "Bad encoding: 0x%x!\n", enc);
return;
}

//设置音频的格式
waveform.wFormatTag = WAVE_FORMAT_PCM; //PCM类型的声音
waveform.nChannels = channels; //声道
waveform.nSamplesPerSec = rate; //每秒采样率
waveform.nAvgBytesPerSec = rate * channels * 2; //每秒多少字节
waveform.nBlockAlign = 4; //我不太清楚,反正4没错
waveform.wBitsPerSample = 16; //signed16编码格式的每采样大小
waveform.cbSize = 0; //额外信息,一般是0

//告诉系统文件打开正常
hasFile = true;
}

void D3DPlay(long n)
{
LPVOID lpPtr1 = new LPVOID;
LPVOID lpPtr2 = new LPVOID;
DWORD length1 = 0, length2 = 0, state = 0;

D3DInit(n); //传递解码后的数据文件大小,便于缓存格式变量创建
dsbd.lpwfxFormat = &waveform; //将读取到的格式传给缓存格式变量
g_pD3DSound->CreateSoundBuffer(&dsbd, &g_pD3DSoundBuffer, NULL);

//打开缓存以便写入,返回两个缓存可写入地址和他们的长度,一般来说第二个地址是没有的
g_pD3DSoundBuffer->Lock(0, n, &lpPtr1, &length1, &lpPtr2, &length2, 0);
memcpy(lpPtr1, buffer, n); //拷贝数据
g_pD3DSoundBuffer->Unlock(lpPtr1, length1, 0, 0); //关闭缓存
g_pD3DSoundBuffer->SetCurrentPosition(0); //设定播放位置从0开始
g_pD3DSoundBuffer->Play(0, 0, DSBPLAY_LOOPING); //播放,循环
//等待播放完成
g_pD3DSoundBuffer->GetStatus(&state);

while ((state == 1) || (state == 5)) //1代表只放一次,5代表循环播放
{
Sleep(200); //每隔200ms检测一次状态
g_pD3DSoundBuffer->GetStatus(&state);
};
printf("Play Over\n");
}

void Play()
{
if (hasFile)
{
long n = mpg123_length(mh) * 16 * 2 / 8; //通过采样总数*每采样比特数*声道/8获得字节数
size_t done = 0;
buffer = (BYTE*)malloc(n);
err = mpg123_read(mh, buffer, n, &done); //读取文件并解码,是的,一句话就完成了
if (err == MPG123_ERR) return;
if ((err == MPG123_DONE) || (err == MPG123_OK)) D3DPlay(done); //若正常解码结束,开始播放
}
}

int main()
{
//读入文件名,只支持英文
CHAR path[30];
cout << "请输入要播放的mp3文件(带后缀名),请和程序放在同一个目录下" << endl;
cin >> path;
Open(path);
Play();
CleanUp();

//不至于播放完了一闪而过
return system("pause");
}
...全文
256 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
dudujerry 2018-08-17
  • 打赏
  • 举报
回复
求大神帮忙啊
赵4老师 2018-08-17
  • 打赏
  • 举报
回复
电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址;
人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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