最近,我一直在用wave文件的形式写歌。然而,我决定尝试一些新的东西:使用二维数组。但是,当我运行程序时,波文件没有播放任何内容。我的目的是创建一个由音符组成的数组,并将数组存储到wave文件的数据部分,以便随着时间的推移,不同的音符正在播放(即我分配的音符):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define A 440.00
#define As 466.16
#define B 493.88
#define C 523.25
#define Cs 554.37
#define D 587.33
#define Ds 622.25
#define E 659.25
#define F 698.46
#define Fs 739.99
#define G 783.99
#define Gs 830.61
int main() {
FILE* fp;
fp = fopen("song.wav", "wb");
if (fp == NULL) {
printf("File does not exist.n");
return EXIT_FAILURE;
}
char ChunkID[4] = "RIFF", Format[4] = "WAVE", Subchunk1ID[4] = "fmt ", Subchunk2ID[4] = "data";
unsigned int ChunkSize, Subchunk1Size, Subchunk2Size;
unsigned short int AudioFormat, NumChannels, BlockAlign, BitsPerSample;
int SampleRate, ByteRate;
ChunkSize = 12 + 24 + 8 - 8 + 5 * 44100 * 2;
Subchunk1Size = 16;
AudioFormat = 1;
NumChannels = 1;
SampleRate = 44100;
ByteRate = 2 * SampleRate;
BitsPerSample = 16;
BlockAlign = NumChannels * BitsPerSample / 8;
Subchunk2Size = 9 * ByteRate;
int i, j;
short int audio[9][9] = {A, B, Cs, D, E, D, Cs, B, A};
float freq, amplitude = 32700;
for (i = 0; i < 9 * SampleRate; i++){
for (j = 0; j == i; j++)
freq = audio[i][j] * 2.0 * M_PI;
*audio[i] = amplitude * sin(freq * i / SampleRate);
}
fwrite(ChunkID, 4, 1, fp);
fwrite(&ChunkSize, 4, 1, fp);
fwrite(Format, 4, 1, fp);
fwrite(Subchunk1ID, 4, 1, fp);
fwrite(&Subchunk1Size, 4, 1, fp);
fwrite(&AudioFormat, 2, 1, fp);
fwrite(&NumChannels, 2, 1, fp);
fwrite(&SampleRate, 4, 1, fp);
fwrite(&ByteRate, 4, 1, fp);
fwrite(&BlockAlign, 2, 1, fp);
fwrite(&BitsPerSample, 2, 1, fp);
fwrite(Subchunk2ID, 4, 1, fp);
fwrite(&Subchunk2Size, 4, 1, fp);
fwrite(audio, 2, 1, fp);
fclose(fp);
return EXIT_SUCCESS;
}
不太确定要写入的是什么曲调。文件,但是一些初始错误:
short int audio[9][9] = {A, B, Cs, D, E, D, Cs, B, A};
创建一个9x9数组,其中a, B等存储在audio[0]中,所有其他值初始化为0。之后,你会试着计算频率,大多数音频值都是0。
for (i = 0; i < 9 * SampleRate; i++){
从SampleRate = 44100
开始,您将很快走出audio
数组的边界。
*audio[i] = amplitude * sin(freq * i / SampleRate);
这一行所做的是,它将计算值存储为一个int在audio[i][0]
中。我不知道为什么你要用一个二维数组当你什么都不做的时候。
调试快乐!
我需要一个单独的数组来存储数据,然后使用嵌套的for循环来存储笔记与时间的关系。修改如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define A 440.00
#define As 466.16
#define B 493.88
#define C 523.25
#define Cs 554.37
#define D 587.33
#define Ds 622.25
#define E 659.25
#define F 698.46
#define Fs 739.99
#define G 783.99
#define Gs 830.61
int main() {
struct WAVE {
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
char Subchunk1ID[4];
unsigned int Subchunk1Size;
unsigned short int AudioFormat;
unsigned short int NumChannels;
int SampleRate;
int ByteRate;
unsigned short int BlockAlign;
unsigned short int BitsPerSample;
char Subchunk2ID[4];
unsigned int Subchunk2Size;
};
struct WAVE w;
FILE* fp;
fp = fopen("song.wav", "wb");
if (fp == NULL) {
printf("File does not exist.n");
return EXIT_FAILURE;
}
strcpy(w.ChunkID, "RIFF");
strcpy(w.Format, "WAVE");
strcpy(w.Subchunk1ID, "fmt ");
strcpy(w.Subchunk2ID, "data");
w.Subchunk1Size = 16;
w.AudioFormat = 1;
w.NumChannels = 1;
w.SampleRate = 44100;
w.ByteRate = 2 * w.SampleRate;
w.BitsPerSample = 16;
w.BlockAlign = w.NumChannels * w.BitsPerSample / 8;
short int audio[9][w.SampleRate / 3];
float amplitude = 32700;
int i, j, numnotes, numdatabytes;
float f[12] = {A, As, B, C, Cs, D, Ds, E, F, Fs, G, Gs};
int notes[9] = {1, 3, 5, 6, 8, 6, 5, 3, 1};
numnotes = sizeof(notes) / 4;
numdatabytes = numnotes * w.ByteRate / 3;
for (j = 0; j < numnotes; j++) {
for (i = 0; i < w.SampleRate / 3; i++)
audio[j][i] = amplitude * sin(2 * M_PI * f[j] * i / w.SampleRate);
}
w.ChunkSize = 12 + 24 + 8 - 8 + numdatabytes;
w.Subchunk2Size = numdatabytes;
fwrite(&w, 44, 1, fp);
for (i = 0; i < numnotes; i++)
fwrite(audio[notes[i]], 2, w.SampleRate / 3, fp);
fclose(fp);
return EXIT_SUCCESS;
}