참고: 아래 사이트는 단순음(pure tone, 순음)을 만들 수 있는 서비스를 제공합니다.
http://onlinetonegenerator.com/
C 언어로 단순음(pure tone, 순음) 웨이브 파일을 만들기
출처: http://karplus4arduino.wordpress.com/2011/10/08/making-wav-files-from-c-programs/
I’m going to try embedding some short pieces of code in this post, and later work out a better way of distributing larger blocks of code.
The code I want to share today consists of a small C file and the associated header for creating WAV files for producing sounds on a laptop or desktop computer. This is not a full-featured WAV file module: the format has a lot of options and I didn’t want the complexity of dealing with all of them. I just wanted to output monophonic sound with a reasonable sampling rate.
08 |
void write_wav( char * filename, unsigned long num_samples, short int * data, int s_rate); |
02 |
* Creates a WAV file from an array of ints. |
03 |
* Output is monophonic, signed 16-bit samples |
05 |
* Fri Jun 18 16:36:23 PDT 2010 Kevin Karplus |
06 |
* Creative Commons license Attribution-NonCommercial |
15 |
void write_little_endian(unsigned int word, int num_bytes, FILE *wav_file) |
20 |
fwrite(&buf, 1,1, wav_file); |
26 |
/* information about the WAV file format from |
30 |
void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate) |
33 |
unsigned int sample_rate; |
34 |
unsigned int num_channels; |
35 |
unsigned int bytes_per_sample; |
36 |
unsigned int byte_rate; |
37 |
unsigned long i; /* counter for samples */ |
39 |
num_channels = 1; /* monoaural */ |
42 |
if (s_rate<=0) sample_rate = 44100; |
43 |
else sample_rate = (unsigned int) s_rate; |
45 |
byte_rate = sample_rate*num_channels*bytes_per_sample; |
47 |
wav_file = fopen(filename, "w"); |
48 |
assert(wav_file); /* make sure it opened */ |
50 |
/* write RIFF header */ |
51 |
fwrite("RIFF", 1, 4, wav_file); |
52 |
write_little_endian(36 + bytes_per_sample* num_samples*num_channels, 4, wav_file); |
53 |
fwrite("WAVE", 1, 4, wav_file); |
55 |
/* write fmt subchunk */ |
56 |
fwrite("fmt ", 1, 4, wav_file); |
57 |
write_little_endian(16, 4, wav_file); /* SubChunk1Size is 16 */ |
58 |
write_little_endian(1, 2, wav_file); /* PCM is format 1 */ |
59 |
write_little_endian(num_channels, 2, wav_file); |
60 |
write_little_endian(sample_rate, 4, wav_file); |
61 |
write_little_endian(byte_rate, 4, wav_file); |
62 |
write_little_endian(num_channels*bytes_per_sample, 2, wav_file); /* block align */ |
63 |
write_little_endian(8*bytes_per_sample, 2, wav_file); /* bits/sample */ |
65 |
/* write data subchunk */ |
66 |
fwrite("data", 1, 4, wav_file); |
67 |
write_little_endian(bytes_per_sample* num_samples*num_channels, 4, wav_file); |
68 |
for (i=0; i< num_samples; i++) { |
69 |
write_little_endian((unsigned int)(data[i]),bytes_per_sample, wav_file); |
Note that the above code is not a full program, just a tiny library routine that can be used to generate WAV files. Here is a test program to generate sine waves (inefficiently) to see if the program works. once you have the basic idea, you can write arbitrary programs to generate WAV files and play them back with QuickTime Player, RealPlayer,Audacity, or any of several other sound-playing programs. This is really old-school computer music, from the days when computers were so slow that quality sounds could not be generated in real time. It provides a good way to get started in learning the algorithms, though, as you don’t need to worry about efficiency or all the details needed to compute samples and provide them to a DAC at exactly the right rate.
09 |
#define S_RATE (44100) |
10 |
#define BUF_SIZE (S_RATE*2) /* 2 second buffer */ |
14 |
int main( int argc, char * argv) |
18 |
float amplitude = 32000; |
22 |
float freq_radians_per_sample = freq_Hz*2*M_PI/S_RATE; |
25 |
for (i=0; i<BUF_SIZE; i++) |
27 |
phase += freq_radians_per_sample; |
28 |
buffer[i] = ( int )(amplitude * sin (phase)); |
31 |
write_wav( "test.wav" , BUF_SIZE, buffer, S_RATE); |