【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 题解(上)
869 0
【CS50x】 Tideman 题解(上)
Online Judge System 中术语含义: OJ、AC、WA、TLE、OLE、MLE、PE、RE、CE
Online Judge System 中术语含义: OJ、AC、WA、TLE、OLE、MLE、PE、RE、CE
3580 0
Online Judge System 中术语含义: OJ、AC、WA、TLE、OLE、MLE、PE、RE、CE
|
存储 Kubernetes 固态存储
【k8s 系列】k8s 学习十二,volume 、namespace
顺带说一下 volume 和 namespace ,咱们就开始分享一下 service 是什么
132 0
|
算法 Go
每日一题---31. 下一个排列[力扣][Go]
每日一题---31. 下一个排列[力扣][Go]
每日一题---31. 下一个排列[力扣][Go]
每日一题---27. 移除元素[力扣][Go]
每日一题---27. 移除元素[力扣][Go]
每日一题---27. 移除元素[力扣][Go]
每日一题---500. 键盘行[力扣][Go]
每日一题---500. 键盘行[力扣][Go]
每日一题---500. 键盘行[力扣][Go]
每日一题---23. 合并K个升序链表[力扣][Go]
每日一题---23. 合并K个升序链表[力扣][Go]
每日一题---23. 合并K个升序链表[力扣][Go]
每日一题 --- 1447. 最简分数[力扣][Go]
每日一题 --- 1447. 最简分数[力扣][Go]
每日一题 --- 1447. 最简分数[力扣][Go]
每日一题 --- 606. 根据二叉树创建字符串[力扣][Go]
每日一题 --- 606. 根据二叉树创建字符串[力扣][Go]
每日一题 --- 606. 根据二叉树创建字符串[力扣][Go]
|
Android开发 C++ 芯片
nios ii小实验——第一个demo指导书
nios ii小实验——第一个demo指导书
199 0
nios ii小实验——第一个demo指导书