好的,这里提供一个纯文字版的音乐播放器的代码,使用了C++标准库和Windows API:
```c++
#include <iostream>
#include <Windows.h>
#include <MMSystem.h>
#include <conio.h>
using namespace std;
// 播放状态枚举
enum PlayState {
STOPPED,
PAUSED,
PLAYING
};
// 播放信息结构体
struct PlayInfo {
PlayState state;
string file_name;
HWAVEOUT h_wave_out;
WAVEFORMATEX wave_format;
char *data_buf;
DWORD data_len;
DWORD cur_pos;
};
// 音频数据处理回调函数
void CALLBACK wave_out_callback(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) {
PlayInfo *play_info = (PlayInfo *)dwInstance;
if (uMsg == WOM_DONE) {
play_info->cur_pos = 0;
play_info->state = STOPPED;
waveOutReset(hwo);
}
}
// 加载音频文件
bool load_wave_file(const string &file_name, PlayInfo &play_info) {
// 打开音频文件
HMMIO h_mmio = mmioOpen(const_cast<char *>(file_name.c_str()), NULL, MMIO_ALLOCBUF | MMIO_READ);
if (h_mmio == NULL) {
cerr << "Error: Cannot open file " << file_name << endl;
return false;
}
// 查找WAVE格式块
MMCKINFO mmck_info_parent;
mmck_info_parent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if (mmioDescend(h_mmio, &mmck_info_parent, NULL, MMIO_FINDRIFF) != MMSYSERR_NOERROR) {
cerr << "Error: Cannot find WAVE chunk" << endl;
mmioClose(h_mmio, 0);
return false;
}
MMCKINFO mmck_info_child;
mmck_info_child.ckid = mmioFOURCC('f', 'm', 't', ' ');
if (mmioDescend(h_mmio, &mmck_info_child, &mmck_info_parent, MMIO_FINDCHUNK) != MMSYSERR_NOERROR) {
cerr << "Error: Cannot find WAVE format chunk" << endl;
mmioClose(h_mmio, 0);
return false;
}
if (mmioRead(h_mmio, reinterpret_cast<HPSTR>(&play_info.wave_format), sizeof(WAVEFORMATEX)) != sizeof(WAVEFORMATEX)) {
cerr << "Error: Cannot read WAVE format" << endl;
mmioClose(h_mmio, 0);
return false;
}
mmioAscend(h_mmio, &mmck_info_child, 0);
// 查找数据块
mmck_info_child.ckid = mmioFOURCC('d', 'a', 't', 'a');
if (mmioDescend(h_mmio, &mmck_info_child, &mmck_info_parent, MMIO_FINDCHUNK) != MMSYSERR_NOERROR) {
cerr << "Error: Cannot find WAVE data chunk" << endl;
mmioClose(h_mmio, 0);
return false;
}
play_info.data_len = mmck_info_child.cksize;
play_info.data_buf = new char[play_info.data_len];
if (mmioRead(h_mmio, play_info.data_buf, play_info.data_len) != static_cast<LONG>(play_info.data_len)) {
cerr << "Error: Cannot read WAVE data" << endl;
delete[] play_info.data_buf;
mmioClose(h_mmio, 0);
return false;
}
mmioClose(h_mmio, 0);
return true;
}
// 播放音频
void play_wave(PlayInfo &play_info) {
if (play_info.state == STOPPED) {
// 打开音频输出设备
if (waveOutOpen(&play_info.h_wave_out, WAVE_MAPPER, &play_info.wave_format, (DWORD_PTR)wave_out_callback, (DWORD_PTR)&play_info, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
cerr << "Error: Cannot open wave output device" << endl;
return;
}
// 向音频输出设备写入数据
WAVEHDR wave_hdr;
ZeroMemory(&wave_hdr, sizeof(WAVEHDR));
wave_hdr.lpData = play_info.data_buf;
wave_hdr.dwBufferLength = play_info.data_len;
if (waveOutPrepareHeader(play_info.h_wave_out, &wave_hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
cerr << "Error: Cannot prepare wave header" << endl;
waveOutClose(play_info.h_wave_out);
return;
}
if (waveOutWrite(play_info.h_wave_out, &wave_hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
cerr << "Error: Cannot write wave data" << endl;
waveOutUnprepareHeader(play_info.h_wave_out, &wave_hdr, sizeof(WAVEHDR));
waveOutClose(play_info.h_wave_out);
return;
}
// 更新播放状态
play_info.cur_pos = 0;
play_info.state = PLAYING;
} else if (play_info.state == PAUSED) {
// 继续播放
waveOutRestart(play_info.h_wave_out);
play_info.state = PLAYING;
}
}
// 暂停音频
void pause_wave(PlayInfo &play_info) {
if (play_info.state == PLAYING) {
waveOutPause(play_info.h_wave_out);
play_info.state = PAUSED;
}
}
// 停止音频
void stop_wave(PlayInfo &play_info) {
if (play_info.state != STOPPED) {
waveOutReset(play_info.h_wave_out);
play_info.cur_pos = 0;
play_info.state = STOPPED;
}
}
// 调节音量
void set_volume(PlayInfo &play_info, int volume) {
if (volume < 0) {
volume = 0;
} else if (volume > 100) {
volume = 100;
}
waveOutSetVolume(play_info.h_wave_out, static_cast<DWORD>((static_cast<UINT>(-1) * volume) / 100));
}
int main(int argc, char **argv) {
PlayInfo play_info;
play_info.state = STOPPED;
play_info.data_buf = NULL;
play_info.data_len = 0;
play_info.cur_pos = 0;
while (true) {
// 显示菜单
cout << "------------------" << endl;
cout << "1. Load file" << endl;
cout << "2. Play" << endl;
cout << "3. Pause" << endl;
cout << "4. Stop" << endl;
cout << "5. Set volume" << endl;
cout << "6. Exit" << endl;
cout << "------------------" << endl;
cout << "Current file: " << play_info.file_name << endl;
cout << "Current position: " << play_info.cur_pos << " / " << play_info.data_len << endl;
cout << "Current state: ";
switch (play_info.state) {
case STOPPED:
cout << "STOPPED" << endl;
break;
case PAUSED:
cout << "PAUSED" << endl;
break;
case PLAYING:
cout << "PLAYING" << endl;
break;
}
cout << "Current volume: " << (waveOutGetVolume(play_info.h_wave_out) * 100) / static_cast<UINT>(-1) << endl;
cout << "Please enter your choice: ";
// 处理用户输入
char choice = _getch();
cout << choice << endl;
switch (choice) {
case '1': {
// 加载文件
string file_name;
cout << "Please enter the file name: ";
cin >> file_name;
cout << endl;
if (load_wave_file(file_name, play_info)) {
play_info.file_name = file_name;
play_info.cur_pos = 0;
play_info.state = STOPPED;
cout << "File loaded successfully" << endl;
}
break;
}
case '2':
// 播放