-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwav.c
151 lines (137 loc) · 3.99 KB
/
wav.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <time.h>
#define SAMPLE_RATE 44100
#define TIME_CNT 10
#define SAMPLE_CNT (SAMPLE_RATE * TIME_CNT)
#define PI 3.14159265358979323846
typedef struct
{
char riff_mark[4];
uint32_t file_size;
char file_type[4];
char format_chunk_marker[4];
uint32_t format_data_length;
uint16_t format_type;
uint16_t channel_no;
uint32_t sample_rate;
uint32_t bit_rate;
uint16_t block_align;
uint16_t bits_per_sample;
char data_header[4];
uint32_t data_file_size;
} __attribute__((packed)) wav_header;
typedef int16_t sample_16;
sample_16 samples[SAMPLE_CNT];
double randr(unsigned int min, unsigned int max)
{
double scaled = (double)rand()/RAND_MAX;
return (max - min +1)*scaled + min;
}
void create_noise(double amplitude){
srand(time(0));
int i = 0;
for (i = 0; i < SAMPLE_CNT; i++){
samples[i]=randr(0, amplitude);
}
}
void create_sine(double frequency, double amplitude){
int i = 0;
for (i = 0; i < SAMPLE_CNT; i++){
samples[i]=sin(2*M_PI*frequency*i/SAMPLE_RATE)*amplitude;
}
}
void create_saw(double frequency, double amplitude){
int i = 0;
for (i = 0; i < SAMPLE_CNT; i++){
samples[i]=fmod(frequency*i/SAMPLE_RATE, 1.0)*amplitude;
}
}
void create_square(double frequency, double amplitude){
int i = 0;
for (i = 0; i < SAMPLE_CNT; i++){
samples[i]=sin(2*M_PI*frequency*i/SAMPLE_RATE) >= 0 ? amplitude : -1*amplitude;
}
}
void write_wav_file(wav_header * header, char * filename){
FILE * f = fopen(filename, "w+");
int i = 0;
fwrite(header, sizeof(wav_header), 1, f);
for (i = 0; i < SAMPLE_CNT; i++){
fwrite(&samples[i], sizeof(sample_16), 1, f);
}
fclose(f);
}
void load_wav_header(wav_header * wav_file, int data_file_size){
strncpy(wav_file->riff_mark, "RIFF", 4);
strncpy(wav_file->file_type, "WAVE", 4);
strncpy(wav_file->format_chunk_marker, "fmt ", 4);
wav_file->format_data_length=16;
wav_file->format_type=1;
wav_file->channel_no=2;
wav_file->sample_rate=SAMPLE_RATE;
wav_file->bits_per_sample=16;
wav_file->bit_rate=wav_file->sample_rate * wav_file->channel_no * wav_file->bits_per_sample / 8;
wav_file->block_align=wav_file->bits_per_sample * wav_file->channel_no / 8;
strncpy(wav_file->data_header, "data", 4);
wav_file->data_file_size=data_file_size;
wav_file->file_size=wav_file->data_file_size+sizeof(wav_header);
printf("%s%d\n","size of struct header: ", sizeof(wav_header));
}
typedef enum {
SINE = 0,
SAW = 1,
SQUARE = 2,
NOISE = 3
} wave_type;
int main(int argc, char * argv[]){
printf("%s\n", "creating wav file");
printf("%s%d\n", "samples:", SAMPLE_CNT);
wav_header wav_header_test;
double frequency=100;
double amplitude=5000;
wave_type wavetype = 0;
int i = 0;
for (i=0; i < argc; i++){
printf("%s\n", argv[i]);
}
if (argc > 1){
frequency = strtod(argv[1], 0);
}
if (argc > 2){
amplitude = strtod(argv[2], 0);
}
if (argc > 3){
wavetype = strtod(argv[3], 0);
}
switch (wavetype){
case NOISE:
create_noise(frequency);
break;
case SINE:
create_sine(frequency, amplitude);
break;
case SAW:
create_saw(frequency, amplitude);
break;
case SQUARE:
create_square(frequency, amplitude);
break;
}
load_wav_header(&wav_header_test, SAMPLE_CNT);
write_wav_file(&wav_header_test, "mywav.wav");
// for (i = 0; i < 2000; i++){
// int j = 0;
// for (j = 0; j < 500+(int)(samples[i]/300); j++){
// printf("%s", " ");
// }
// printf("%s\n", "-");
// }
printf("%s\n", "Wave Info:");
printf("%s%f\n", " Frequency:", frequency);
printf("%s%f\n", " Amplitude:", amplitude);
printf("%s%d\n", " Wave Type:", wavetype);
}