diff --git a/11/homework29/control.c b/11/homework29/control.c new file mode 100644 index 0000000000000000000000000000000000000000..4e909e31a6941d7b7651aa6fb817dcadcfcaeddb --- /dev/null +++ b/11/homework29/control.c @@ -0,0 +1,435 @@ +#include +#include +#include +#include "control.h" + +// 设置音频采集开关的函数 +// card: 声卡名称 +// selem: 控制项名称 +// enable: 开关状态 +int set_capture_switch(const char* card, const char* selem, bool enable) { + int err; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + + // 打开混音器 + if ((err = snd_mixer_open(&handle, 0)) < 0) { + fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err)); + return err; + } + + // 附加控制接口到混音器 + if ((err = snd_mixer_attach(handle, card)) < 0) { + fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 注册混音器 + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { + fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 加载混音器元素 + if ((err = snd_mixer_load(handle)) < 0) { + fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 分配简单元素ID + snd_mixer_selem_id_alloca(&sid); + + // 设置简单元素的名称 + snd_mixer_selem_id_set_name(sid, selem); + + // 查找简单元素 + snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid); + if (!elem) { + fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0); + snd_mixer_close(handle); + return -ENOENT; + } + + // 设置采集开关(启用或禁用) + if ((err = snd_mixer_selem_set_capture_switch_all(elem, enable ? 1 : 0)) < 0) { + fprintf(stderr, "Unable to set capture switch: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 关闭混音器 + snd_mixer_close(handle); + + return 0; // 成功 +} + +// 设置音频回放开关的函数 +// card: 声卡名称 +// selem: 控制项名称 +// enable: 开关状态 +int set_playback_switch(const char* card, const char* selem, bool enable) { + int err; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + + // 打开混音器 + if ((err = snd_mixer_open(&handle, 0)) < 0) { + fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err)); + return err; + } + + // 附加控制接口到混音器 + if ((err = snd_mixer_attach(handle, card)) < 0) { + fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 注册混音器 + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { + fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 加载混音器元素 + if ((err = snd_mixer_load(handle)) < 0) { + fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 分配简单元素ID + snd_mixer_selem_id_alloca(&sid); + + // 设置简单元素的名称 + snd_mixer_selem_id_set_name(sid, selem); + + // 查找简单元素 + snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid); + if (!elem) { + fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0); + snd_mixer_close(handle); + return -ENOENT; + } + + // 设置回放开关(启用或禁用) + if ((err = snd_mixer_selem_set_playback_switch_all(elem, enable ? 1 : 0)) < 0) { + fprintf(stderr, "Unable to set playback switch: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 关闭混音器 + snd_mixer_close(handle); + + return 0; // 成功 +} + +// 获取音频采集音量 +// card: 声卡名称 +// selem: 控制项名称 +// 返回值: 当前音量 +int get_capture_volume(const char* card, const char* selem) +{ + int err; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + + // 打开混音器 + if ((err = snd_mixer_open(&handle, 0)) < 0) { + fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err)); + return err; + } + + // 附加控制接口到混音器 + if ((err = snd_mixer_attach(handle, card)) < 0) { + fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 注册混音器 + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { + fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 加载混音器元素 + if ((err = snd_mixer_load(handle)) < 0) { + fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 分配简单元素ID + snd_mixer_selem_id_alloca(&sid); + + // 设置简单元素的名称 + snd_mixer_selem_id_set_name(sid, selem); + + // 查找简单元素 + snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid); + if (!elem) { + fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0); + snd_mixer_close(handle); + return -ENOENT; + } + + // 获取采集通道音量 + long volume = 0; + if ((err = snd_mixer_selem_get_capture_volume(elem, 0, &volume)) < 0) { + fprintf(stderr, "Unable to get capture volume: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 关闭混音器 + snd_mixer_close(handle); + + return volume; // 成功返回音量 +} + +// 获取音频回放通道音量 +// card: 声卡名称 +// selem: 控制项名称 +// 返回值: 当前音量 +int get_playback_volume(const char* card, const char* selem) { + int err; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + + // 打开混音器 + if ((err = snd_mixer_open(&handle, 0)) < 0) { + fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err)); + return err; + } + + // 附加控制接口到混音器 + if ((err = snd_mixer_attach(handle, card)) < 0) { + fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 注册混音器 + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { + fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 加载混音器元素 + if ((err = snd_mixer_load(handle)) < 0) { + fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 分配简单元素ID + snd_mixer_selem_id_alloca(&sid); + + // 设置简单元素的名称 + snd_mixer_selem_id_set_name(sid, selem); + + // 查找简单元素 + snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid); + if (!elem) { + fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0); + snd_mixer_close(handle); + return -ENOENT; + } + + // 获取回放通道音量 + long volume = 0; + if ((err = snd_mixer_selem_get_playback_volume(elem, 0, &volume)) < 0) { + fprintf(stderr, "Unable to get playback volume: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 关闭混音器 + snd_mixer_close(handle); + + return volume; // 成功返回音量 +} + +// 设置音频采集音量 +// card: 声卡名称 +// selem: 控制项名称 +// volume: 设置音量 +// 返回值: 成功返回设置后的音量,失败返回错误码 +int set_capture_volume(const char* card, const char* selem, long volume) +{ + int err; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + + // 打开混音器 + if ((err = snd_mixer_open(&handle, 0)) < 0) { + fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err)); + return err; + } + + // 附加控制接口到混音器 + if ((err = snd_mixer_attach(handle, card)) < 0) { + fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 注册混音器 + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { + fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 加载混音器元素 + if ((err = snd_mixer_load(handle)) < 0) { + fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 分配简单元素ID + snd_mixer_selem_id_alloca(&sid); + + // 设置简单元素的名称 + snd_mixer_selem_id_set_name(sid, selem); + + // 查找简单元素 + snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid); + if (!elem) { + fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0); + snd_mixer_close(handle); + return -ENOENT; + } + + // 获取音量范围 + long min, max; + if ((err = snd_mixer_selem_get_capture_volume_range(elem, &min, &max)) < 0) + { + fprintf(stderr, "Unable to get capture volume range: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + if (volume < min) + { + volume = min; + } + + if (volume > max) + { + volume = max; + } + + // 设置采集通道音量 + if ((err = snd_mixer_selem_set_capture_volume_all(elem, volume)) < 0) { + fprintf(stderr, "Unable to set capture volume: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 关闭混音器 + snd_mixer_close(handle); + + return volume; // 成功 +} + +// 设置音频回放通道音量 +// card: 声卡名称 +// selem: 控制项名称 +// volume: 设置音量 +// 返回值: 成功返回设置后的音量,失败返回错误码 +int set_playback_volume(const char* card, const char* selem, long volume) +{ + int err; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + + // 打开混音器 + if ((err = snd_mixer_open(&handle, 0)) < 0) { + fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err)); + return err; + } + + // 附加控制接口到混音器 + if ((err = snd_mixer_attach(handle, card)) < 0) { + fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 注册混音器 + if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { + fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 加载混音器元素 + if ((err = snd_mixer_load(handle)) < 0) { + fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 分配简单元素ID + snd_mixer_selem_id_alloca(&sid); + + // 设置简单元素的名称 + snd_mixer_selem_id_set_name(sid, selem); + + // 查找简单元素 + snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid); + if (!elem) { + fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0); + snd_mixer_close(handle); + return -ENOENT; + } + + // 获取音量范围 + long min, max; + if ((err = snd_mixer_selem_get_playback_volume_range(elem, &min, &max)) < 0) + { + fprintf(stderr, "Unable to get playback volume range: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + if (volume < min) + { + volume = min; + } + + if (volume > max) + { + volume = max; + } + + // 设置回放通道音量 + if ((err = snd_mixer_selem_set_playback_volume_all(elem, volume)) < 0) { + fprintf(stderr, "Unable to set playback volume: %s\n", snd_strerror(err)); + snd_mixer_close(handle); + return err; + } + + // 关闭混音器 + snd_mixer_close(handle); + + return volume; // 成功返回设置后音量 +} + +// int main(int argc, char** argv) +// { +// printf("Playback Vol: %d\n", get_playback_volume("hw:0", "Analog")); +// printf("New Playback Vol: %d\n", set_playback_volume("hw:0", "Analog", atoi(argv[1]))); + +// return 0; +// } diff --git a/11/homework29/firsthomework.c b/11/homework29/firsthomework.c new file mode 100644 index 0000000000000000000000000000000000000000..98ad94db3dc08b7656a2583e64d4d549a774a653 --- /dev/null +++ b/11/homework29/firsthomework.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include "record.h" +#define GPIO_LINE 9 // 定义GPIO线的编号,这里是PF9 + +// // 假设 record_start 和 record_stop 函数的声明 +// snd_pcm_t *record_start(const char *device, snd_pcm_format_t format, unsigned int channels, unsigned int rate, snd_pcm_uframes_t *period); +// void record_stop(snd_pcm_t *handle); + +int main(void) { + struct gpiod_chip *chip; // 指向GPIO芯片的指针 + struct gpiod_line *line; // 指向GPIO线的指针 + int value, last_value; // 当前值和上一次的值,用于检测按钮状态变化 + snd_pcm_t *capture = NULL; // PCM设备句柄,用于音频录制 + snd_pcm_uframes_t period; // 每个周期的帧数 + char *buffer; // 缓冲区,用于存储录制的音频数据 + FILE *pcm_file; // 输出PCM文件的指针 + int err; // 错误码 + + // 打开GPIO芯片 + chip = gpiod_chip_open_by_label("GPIOF"); + if (!chip) { + perror("打开GPIO芯片失败"); + return 1; + } + + // 获取指定的GPIO线 + line = gpiod_chip_get_line(chip, GPIO_LINE); + if (!line) { + perror("获取GPIO线失败"); + gpiod_chip_close(chip); + return 1; + } + + // 将GPIO线设置为输入模式 + if (gpiod_line_request_input(line, "key1")) { + perror("请求将GPIO线设置为输入模式失败"); + gpiod_chip_close(chip); + return 1; + } + + // 获取初始的GPIO线值 + last_value = gpiod_line_get_value(line); + + // 无限循环检测GPIO线值的变化 + while (1) { + // 获取当前的GPIO线值 + value = gpiod_line_get_value(line); + + // 如果当前值与上一次的值不同,说明按键状态发生了变化 + if (value != last_value) { + // 按钮按下时 + if (value == 0 && capture == NULL) { + printf("key pressed\n"); + + // 开始录音 + capture = record_start("hw:0,1", SND_PCM_FORMAT_S16_LE, 2, 44100, &period); + if (!capture) { + perror("录音启动失败"); + gpiod_chip_close(chip); + return 1; + } + + // 分配缓冲区用于存储音频数据 + buffer = (char *)malloc(snd_pcm_frames_to_bytes(capture, period)); + if (!buffer) { + perror("分配缓冲区失败"); + record_stop(capture); + gpiod_chip_close(chip); + return 1; + } + + // 打开输出PCM文件 + pcm_file = fopen("output.pcm", "wb"); + if (!pcm_file) { + perror("打开输出文件失败"); + free(buffer); // 释放缓冲区 + record_stop(capture); // 关闭PCM设备 + gpiod_chip_close(chip); + return 1; + } + + printf("Recording...\n"); // 输出录音开始提示 + } + // 按钮释放时 + else if (value == 1 && capture != NULL) { + printf("key released\n"); + + // 停止录音 + free(buffer); // 释放缓冲区 + fclose(pcm_file); // 关闭输出文件 + record_stop(capture); // 停止音频采集 + capture = NULL; // 重置capture指针 + + printf("Recording stopped.\n"); // 输出录音停止提示 + } + + // 更新上一次的值为当前值 + last_value = value; + } + + // 如果正在录音,继续读取音频数据 + if (capture != NULL) { + snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); + if (frames < 0) { + fprintf(stderr, "读取音频数据出错: %s\n", snd_strerror(frames)); + snd_pcm_recover(capture, frames, 0); // 尝试恢复PCM设备 + } + // 将读取的数据写入输出文件 + fwrite(buffer, snd_pcm_frames_to_bytes(capture, frames), 1, pcm_file); + } + + // 延时100毫秒,防止检测过于频繁 + //usleep(100000); + } + + // 释放GPIO线资源 + gpiod_line_release(line); + // 关闭GPIO芯片 + gpiod_chip_close(chip); + + return 0; +} diff --git a/11/homework29/record.c b/11/homework29/record.c new file mode 100644 index 0000000000000000000000000000000000000000..56899d3d93bc5982cb5d240fdef3818a4c43e136 --- /dev/null +++ b/11/homework29/record.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include // 用于处理错误码 + +//开始录音 +snd_pcm_t* record_start(const char* name, + snd_pcm_format_t format, + unsigned int channel, + unsigned int rate, + snd_pcm_uframes_t* period) +{ + snd_pcm_t *capture; // PCM设备句柄 + snd_pcm_hw_params_t *params; // PCM硬件参数 + int err; // 用于存储错误码 + int dir; + + // 打开PCM设备用于录音(捕捉) + if ((err = snd_pcm_open(&capture, name, SND_PCM_STREAM_CAPTURE, 0)) < 0) { + fprintf(stderr, "Error opening PCM device %s: %s\n", name, snd_strerror(err)); + return NULL; + } + + // 分配参数对象,并用默认值填充 + snd_pcm_hw_params_alloca(¶ms); + snd_pcm_hw_params_any(capture, params); + + // 设置参数 + // 设置访问类型:交错模式 + if ((err = snd_pcm_hw_params_set_access(capture, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { + fprintf(stderr, "Error setting access: %s\n", snd_strerror(err)); + snd_pcm_close(capture); + return NULL; + } + // 设置数据格式:16位小端 + if ((err = snd_pcm_hw_params_set_format(capture, params, format)) < 0) { + fprintf(stderr, "Error setting format: %s\n", snd_strerror(err)); + snd_pcm_close(capture); + return NULL; + } + // 设置声道数:立体声 + if ((err = snd_pcm_hw_params_set_channels(capture, params, channel)) < 0) { + fprintf(stderr, "Error setting channels: %s\n", snd_strerror(err)); + snd_pcm_close(capture); + return NULL; + } + // 设置采样率 + if ((err = snd_pcm_hw_params_set_rate_near(capture, params, &rate, &dir)) < 0) { + fprintf(stderr, "Error setting rate: %s\n", snd_strerror(err)); + snd_pcm_close(capture); + return NULL; + } + printf("sample rate: %d Hz\n", rate); + + // 设置硬件参数 + if ((err = snd_pcm_hw_params(capture, params)) < 0) { + fprintf(stderr, "Error setting HW params: %s\n", snd_strerror(err)); + snd_pcm_close(capture); + return NULL; + } + + // 获取周期大小 + snd_pcm_hw_params_get_period_size(params, period, &dir); + + return capture; +} + +//停止录音 +void record_stop(snd_pcm_t* capture) +{ + snd_pcm_drain(capture); // 排空PCM设备 + snd_pcm_close(capture); // 关闭PCM设备 +} + +// int main() +// { +// snd_pcm_t *capture; // PCM设备句柄 +// snd_pcm_uframes_t period; // 每个周期的帧数 +// char *buffer; // 缓冲区,用于存储采集到的音频数据 +// FILE *pcm_file; // 输出PCM文件 +// int err; // 用于存储错误码 + +// capture = record_start("hw:0,1", SND_PCM_FORMAT_S16_LE, 2, 44100, &period); +// if (!capture) +// { +// return 1; +// } + +// printf("period: %d frames\n", period); + +// buffer = (char *) malloc(snd_pcm_frames_to_bytes(capture, period)); // 分配缓冲区 +// if (!buffer) { +// perror("malloc"); +// record_stop(capture); +// return 1; +// } + +// // 打开输出文件 +// pcm_file = fopen("output.pcm", "wb"); +// if (!pcm_file) { +// perror("Error opening output file"); +// free(buffer); // 释放缓冲区 +// record_stop(capture); // 关闭PCM设备 +// return 1; +// } + +// // 录制数据 +// printf("Recording... Press Ctrl+C to stop.\n"); +// while (1) { +// snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); // 从PCM设备读取数据 +// if (frames < 0) +// { +// fprintf(stderr, "Error from read: %s\n", snd_strerror(frames)); +// snd_pcm_recover(capture, frames, 0); +// } + +// fwrite(buffer, snd_pcm_frames_to_bytes(capture, frames), 1, pcm_file); // 将读取的数据写入文件 +// } + +// // 清理资源 +// free(buffer); // 释放缓冲区 +// fclose(pcm_file); // 关闭文件 +// record_stop(capture); + +// return 0; +// } diff --git a/11/homework29/secondhomework.c b/11/homework29/secondhomework.c new file mode 100644 index 0000000000000000000000000000000000000000..dbf75ace4adcf9166370e0dc5b6b9c81e9f62217 --- /dev/null +++ b/11/homework29/secondhomework.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include + +#include "control.h" +#define GPIO_LINE_K2 7 // 定义K2按钮的GPIO线编号 +#define GPIO_LINE_K3 8 // 定义K3按钮的GPIO线编号 + + +int main(void) { + struct gpiod_chip *chip; // 定义指向GPIO芯片的指针 + struct gpiod_line *line_k2; // 定义指向K2按钮GPIO线的指针 + struct gpiod_line *line_k3; // 定义指向K3按钮GPIO线的指针 + int value_k2, last_value_k2; // 当前和上一次的K2按钮值 + int value_k3, last_value_k3; // 当前和上一次的K3按钮值 + long volume; // 当前音量 + + // 打开GPIO芯片 + chip = gpiod_chip_open_by_label("GPIOF"); + if (!chip) { + perror("打开GPIO芯片失败"); + return 1; + } + + // 获取K2按钮的GPIO线 + line_k2 = gpiod_chip_get_line(chip, GPIO_LINE_K2); + if (!line_k2) { + perror("获取K2按钮GPIO线失败"); + gpiod_chip_close(chip); + return 1; + } + + // 获取K3按钮的GPIO线 + line_k3 = gpiod_chip_get_line(chip, GPIO_LINE_K3); + if (!line_k3) { + perror("获取K3按钮GPIO线失败"); + gpiod_chip_close(chip); + return 1; + } + + // 将K2按钮GPIO线设置为输入模式 + if (gpiod_line_request_input(line_k2, "key_k2")) { + perror("请求K2按钮GPIO线输入模式失败"); + gpiod_chip_close(chip); + return 1; + } + + // 将K3按钮GPIO线设置为输入模式 + if (gpiod_line_request_input(line_k3, "key_k3")) { + perror("请求K3按钮GPIO线输入模式失败"); + gpiod_chip_close(chip); + return 1; + } + + // 获取初始的按钮状态 + last_value_k2 = gpiod_line_get_value(line_k2); + last_value_k3 = gpiod_line_get_value(line_k3); + + // 获取当前音量 + volume = get_playback_volume("hw:0", "Master"); + + // 无限循环检测按钮状态变化 + while (1) { + // 获取K2按钮的当前状态 + value_k2 = gpiod_line_get_value(line_k2); + + // 获取K3按钮的当前状态 + value_k3 = gpiod_line_get_value(line_k3); + + // 检测K2按钮状态变化 + if (value_k2 != last_value_k2) { + // 按下K2按钮 + if (value_k2 == 0) { + printf("K2 pressed\n"); + volume += 5; // 增加音量 + volume = set_playback_volume("hw:0", "Analog", volume); + printf("New Playback Vol: %ld\n", volume); + } + // 更新K2按钮状态 + last_value_k2 = value_k2; + } + + // 检测K3按钮状态变化 + if (value_k3 != last_value_k3) { + // 按下K3按钮 + if (value_k3 == 0) { + printf("K3 pressed\n"); + volume -= 5; // 减少音量 + volume = set_playback_volume("hw:0", "Analog", volume); + printf("New Playback Vol: %ld\n", volume); + } + // 更新K3按钮状态 + last_value_k3 = value_k3; + } + + // 延时100毫秒,防止检测过于频繁 + usleep(100000); + } + + // 释放GPIO线资源 + gpiod_line_release(line_k2); + gpiod_line_release(line_k3); + + // 关闭GPIO芯片 + gpiod_chip_close(chip); + + return 0; +} diff --git a/11/main.c b/11/main.c new file mode 100644 index 0000000000000000000000000000000000000000..c45c06b42784c0e93fbfd6249a0355e6dff5c95b --- /dev/null +++ b/11/main.c @@ -0,0 +1,56 @@ +#include +#include +/* 1990年1月1日 是星期一 */ + +bool is_valid(int year,int month,int day) +{ + if(year<1990) + return false; + if(month<1||month>12) + return false; +} +//判断润年 +bool year_is_leap(int i) +{ + return(i % 4 == 0 && i % 100 != 0) || i % 400 == 0; +} +//返回從1月1日到輸入月份之間的天數 +int get_monthdays(int mounth,bool leap) +{ + int days=0; + int a[]={31,28+!!leap,31,30,31,30,31,31,30,31,30,31}; + for(int i=0;i