- 环境配置
- 安装C语言开发环境,推荐使用gcc编译器。
- 安装SDL库,SDL是一套跨平台的游戏开发库,可以方便的创建图形界面和音频效果。
-
在代码中包含SDL库头文件以及链接SDL静态库或者动态库。
-
构建程序框架
- 创建一个窗口用于展示钢琴的键盘和播放音频。
- 定义音符的频率和时长,将每个音符映射到对应的键盘上。
-
监听键盘事件,根据用户的输入播放相应的音符。
-
程序实现
示例1:初始化SDL库,创建钢琴窗口
#include <stdio.h>
#include <SDL.h>
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
int main(int argc, char *argv[]) {
// 初始化SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
printf("SDL初始化失败!错误:%s\n", SDL_GetError());
return 1;
}
// 创建窗口
SDL_Window *window = SDL_CreateWindow("Piano",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
if (window == NULL) {
printf("窗口创建失败!错误:%s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// 等待窗口关闭
bool quit = false;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
}
// 退出SDL
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
示例2:监听键盘事件,根据用户输入播放音效
#include <stdio.h>
#include <SDL.h>
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
bool isKeyDown(SDL_Keycode key) {
const Uint8 *state = SDL_GetKeyboardState(NULL);
return state[SDL_GetScancodeFromKey(key)];
}
int main(int argc, char *argv[]) {
// 初始化SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
printf("SDL初始化失败!错误:%s\n", SDL_GetError());
return 1;
}
// 创建窗口
SDL_Window *window = SDL_CreateWindow("Piano",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
if (window == NULL) {
printf("窗口创建失败!错误:%s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// 初始化音频子系统
if (SDL_AudioInit(NULL) != 0) {
printf("音频子系统初始化失败!错误:%s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
// 音频参数
SDL_AudioSpec want, have;
SDL_memset(&want, 0, sizeof(want));
want.freq = 48000;
want.format = AUDIO_S16SYS;
want.channels = 2;
want.samples = 4096;
want.callback = NULL;
// 打开音频设备
SDL_AudioDeviceID device = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
if (device == 0) {
printf("音频设备打开失败!错误:%s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
// 提示音符按键
printf("请按下以下按键来弹奏钢琴:\nq w e r t y u i o p\n");
// 音效数据
int notes[10] = {330, 349, 392, 440, 494, 523, 587, 659, 698, 784};
bool isPlay[10] = {false};
// 等待窗口关闭
bool quit = false;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
// 播放对应的音符
if (isKeyDown(SDLK_q) && !isPlay[0]) {
isPlay[0] = true;
SDL_QueueAudio(device, ¬es[0], sizeof(int));
}
if (isKeyDown(SDLK_w) && !isPlay[1]) {
isPlay[1] = true;
SDL_QueueAudio(device, ¬es[1], sizeof(int));
}
if (isKeyDown(SDLK_e) && !isPlay[2]) {
isPlay[2] = true;
SDL_QueueAudio(device, ¬es[2], sizeof(int));
}
if (isKeyDown(SDLK_r) && !isPlay[3]) {
isPlay[3] = true;
SDL_QueueAudio(device, ¬es[3], sizeof(int));
}
if (isKeyDown(SDLK_t) && !isPlay[4]) {
isPlay[4] = true;
SDL_QueueAudio(device, ¬es[4], sizeof(int));
}
if (isKeyDown(SDLK_y) && !isPlay[5]) {
isPlay[5] = true;
SDL_QueueAudio(device, ¬es[5], sizeof(int));
}
if (isKeyDown(SDLK_u) && !isPlay[6]) {
isPlay[6] = true;
SDL_QueueAudio(device, ¬es[6], sizeof(int));
}
if (isKeyDown(SDLK_i) && !isPlay[7]) {
isPlay[7] = true;
SDL_QueueAudio(device, ¬es[7], sizeof(int));
}
if (isKeyDown(SDLK_o) && !isPlay[8]) {
isPlay[8] = true;
SDL_QueueAudio(device, ¬es[8], sizeof(int));
}
if (isKeyDown(SDLK_p) && !isPlay[9]) {
isPlay[9] = true;
SDL_QueueAudio(device, ¬es[9], sizeof(int));
}
// 监听音效结束事件,重置按键状态
SDL_Delay(10); // 避免CPU资源占用过高
int queued = SDL_GetQueuedAudioSize(device);
if (queued == 0) {
for (int i = 0; i < 10; i++) {
isPlay[i] = false;
}
}
}
// 关闭音频设备
SDL_CloseAudioDevice(device);
SDL_AudioQuit();
// 退出SDL
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用C语言编写钢琴小程序 - Python技术站