【CS50x】Volume 题解

简介: 【CS50x】Volume 题解

前言


CS50x 是哈佛大学推出的一门知名公开课,本课程是一门计算机科学的导论课程,适合于对计算机科学感兴趣的任何人学习,不需要任何基础。通过学习本课程有助于对计算机科学的体系建立一个基本的概念,其学习内容如下:


image.png


WAV



本题要求我们读取以 .wav 为后缀的音频文件,然后修改其音量。


要修改 WAV 文件的音量,首先我们需要了解 WAV 文件格式,WAV 文件是表示音频的通用文件格式。


WAV 文件以样本的形式存储音频,数字表示某个特定时间点某个音频信号的值。

从一个44字节的“头部”开始,其中包含文件本身的信息,包括文件的大小、每秒的样本数以及每个样本的大小。


在头部之后,WAV 文件包含一系列样本,每个样本都是一个2字节(16位)的整数,表示特定时间点的音频信号,我们可以将每个样本值乘以2.0,以得到原始音频音量加倍的效果,同理每个样本乘以0.5将会减少一半的音量。


所以这里我们将会用到 C 语言的两种类型:uint8_t 以及 int16_t,分别读取头部和样本。你可以从命名中看出他们的作用,uint8 即 unsigned int 8,用来读取8位无符号整数(即非负数),int16 用来读取16位有符号整数。


Volume


要求使用命令行输入形如 ./volume INPUT.wav OUTPUT.wav 2.0 的命令来获得输入及输出后的文件,2.0即加倍原始音量。

首先我们需要通过 fopen() 来读写文件,通过不同参数 r 和 w 来达到效果,别忘了最后用 fclose() 关闭文件流,否则会造成内存泄漏


#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// 头部大小
const int HEADER_SIZE = 44;
int main(int argc, char *argv[])
{
    // 检查命令行参数
    if (argc != 4)
    {
        printf("Usage: ./volume input.wav output.wav factor\n");
        return 1;
    }
    FILE *input = fopen(argv[1], "r");
    if (input == NULL)
    {
        printf("Could not open file.\n");
        return 1;
    }
    FILE *output = fopen(argv[2], "w");
    if (output == NULL)
    {
        printf("Could not open file.\n");
        return 1;
    }
    // TODO
    fclose(input);
    fclose(output);
}
复制代码


获得需要的文件流后,我们就可以开始改造音量了。

通过 fread()fwrite() 函数来进行读写,参数为(读写的文件流,每次读写的大小,读写次数,读写的文件流),仿照去写就ok了:


// TODO
// 将因子从string转换成float类型
float factor = atof(argv[3]);
// 将原本的头部复制到输出文件中
uint8_t header[HEADER_SIZE];
fread(header, HEADER_SIZE, 1, input);
fwrite(header, HEADER_SIZE, 1, output);
int16_t buffer;
while (fread(&buffer, sizeof(int16_t), 1, input))
{
  // 将每个样本乘以因子后写入输出文件
  buffer *= factor;
  fwrite(&buffer, sizeof(int16_t), 1, output);
}


目录
相关文章
|
算法
【CS50x】 Tideman 题解(上)
【CS50x】 Tideman 题解(上)
1074 0
【CS50x】 Tideman 题解(上)
|
11月前
|
资源调度 JavaScript 前端开发
Van-Nav:新年,将自己学习的项目地址统一整理搭建自己的私人导航站,供自己后续查阅使用,做技术的同学应该都有一个自己网站的梦想
嗨,大家好,我是小华同学。今天为大家介绍一个基于Vue.js开发的导航组件库——Van-Nav。它支持响应式设计、多级菜单、丰富的配置选项和多种动画效果,适用于企业官网、电商平台、内容管理系统和个人博客等多种场景。轻松集成到Vue项目中,提供清晰有序的导航体验。关注我们获取更多优质开源项目和高效工作学习方法。
1061 68
|
人工智能 数据可视化 程序员
史上最全盘点:一文告诉你低代码(Low-Code)是什么?为什么要用?
在后疫情时代,低代码(Low-Code)+ 人工智能(AI)的组合被认为是加速社会数字化转型的重要技术。低代码通过可视化和模型驱动的理念,结合云原生和多端体验技术,显著提升了开发效率和灵活性。它不仅让专业开发者受益,还使业务人员成为“平民开发者”,弥补了专业人才缺口。此外,低代码平台能够快速响应市场变化,帮助企业构建各种应用,如四川某制造企业仅用一个月就搭建出一套内部协作和生产监控系统。结合AI的能力,低代码平台还能实现智能化的建议和优化,进一步提升用户体验和开发速度。
|
12月前
|
存储 Java Linux
【Maven】——基础入门,插件安装、配置和简单使用,Maven如何设置国内源
Maven插件安装,Maven项目构建,依赖管理,Haven Help插件,Maven仓库,Maven如何设置国内源
|
存储 算法 搜索推荐
【算法】七大经典排序(插入,选择,冒泡,希尔,堆,快速,归并)(含可视化算法动图,清晰易懂,零基础入门)
【算法】七大经典排序(插入,选择,冒泡,希尔,堆,快速,归并)(含可视化算法动图,清晰易懂,零基础入门)
458 1
|
监控 程序员 开发工具
如何规范Git提交-参考阿里云开发者社区
这篇文章分享了如何规范Git提交,介绍了commit message的格式规范,并通过webhook监控机制来确保代码提交的规范性,从而提高研发效率和代码维护质量。
|
Java
什么是Java内部类,为什么使用它?
【4月更文挑战第13天】
516 1
|
消息中间件 传感器 网络协议
阿里云MQTT简介和使用流程
以下是内容的摘要: 该文主要介绍了在阿里云上搭建 MQTT 服务器的步骤。首先,需要注册阿里云账号并进行实名认证。然后,购买阿里云 MQTT 实例,选择合适的类型、地域、连接和消息限制。接着,创建产品和设备,命名并上线,获取 MQTT 连接的相关信息,包括 ProductKey、DeviceName 和 DeviceSecret。通过提供的 MQTT.fx 工具,设置 MQTT 客户端连接参数,包括 Broker 地址、端口、用户名和密码。最后,使用 MQTT.fx 测试连接,实现数据的上报和接收,验证 MQTT 服务器的配置是否成功。
|
存储 前端开发 JavaScript
软件设计文档编写指南
软件设计文档编写指南