出于病态的好奇心,我一直试图想出一个程序,它将产生一个4秒440A的C音符。然而,在VLC中播放输出的文件不会产生任何音乐。
使用维基百科作为这个页面上.au标题的指南:http://en.wikipedia.org/wiki/Au_file_format我想出了这个:
#include <stdio.h>
#include <math.h>
#define MAGIC_NUM 0x2e736e64
#define DEFAULT_OFFSET 24
#define UNKNOWN_SIZE 0xffffffff
#define BIT_32_PCM 5
#define STEREO 2
#define SAMPLE_RATE 8000
#define DURATION 4
#define MIDDLE_A 440
int main(int argc, char** argv) {
FILE* sound;
sound = fopen("output.au", "w");
//write header
fputc(MAGIC_NUM, sound);
fputc(DEFAULT_OFFSET, sound);
fputc(UNKNOWN_SIZE, sound);
fputc(BIT_32_PCM, sound);
fputc(SAMPLE_RATE, sound);
fputc(STEREO, sound);
//write a duration of a constant note
int i;
for(i = 0; i <= DURATION * SAMPLE_RATE; i++) {
fputc((int)floor(MIDDLE_A * sin(i)), sound);
}
fclose(sound);
return 0;
}有人知道我做错了什么吗?
发布于 2011-03-30 16:35:39
您不希望文件以文本形式打开-它可能会对任何已编写的换行符做一些有趣的事情。
sound = fopen("output.au", "wb");你不想写字符-使用fwrite而不是fputc
fwrite(".snd", 1, 4, sound);还要注意,.au文件是高字节顺序的-如果你在x86或x86_64上,你的原生字节顺序是小字节顺序,你需要在写入数据之前转换数据。
发布于 2011-03-30 16:45:48
问题是fputc,它只输出一个字符。例如,您不能使用fputc一次编写MAGIC_NUM。一种解决方案是定义您自己的fput函数:
// write a word (2 bytes)
void fputw (unsigned int value, FILE* f)
{
fputc(value & 0xff, f);
fputc(value >> 8 & 0xff, f);
}
// write a dword (4 bytes)
void fputdw(unsigned int value, FILE* f)
{
fputc(value & 0xff, f);
fputc(value >> 8 & 0xff, f);
fputc(value >> 16 & 0xff, f);
fputc(value >> 24 & 0xff, f);
}
//write header
fputdw(MAGIC_NUM, sound);
fputdw(DEFAULT_OFFSET, sound);
fputdw(UNKNOWN_SIZE, sound);
fputdw(BIT_32_PCM, sound);
fputdw(SAMPLE_RATE, sound);
fputdw(STEREO, sound);发布于 2011-03-30 21:39:35
关于一次写一个字符的评论是针对这个问题的,但这里还有更根本的问题--
sin()函数的输出是一个范围在-1.0之间的浮点数。+1.0;然后取其下限,它将始终为零。伪代码类似(未测试...)
SAMPLE_RATE = 44100.0
FREQ = 440.0
PI = 3.14159
DURATION = 4
AMPLITUDE = 1.0
ANGULAR_FREQ = (2 * PI * FREQ) / SAMPLE_RATE
for (int i = 0; i < (int) DURATION * SAMPLE_RATE; ++i)
{
// get sample value in range -1.0 .. + 1.0
floatSample = AMPLITUDE * sin(i * ANGULAR_FREQ)
// convert to correctly scaled integer representation
intSample = (int) floor(0x7FFFFFFF * floatSample);
// write to file, send out DAC, whatever...
}https://stackoverflow.com/questions/5483816
复制相似问题