-
Notifications
You must be signed in to change notification settings - Fork 1
/
wtout.c
159 lines (140 loc) · 5.79 KB
/
wtout.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
152
153
154
155
156
157
158
159
/* lopwav. the idea is to lop off either the start or the end of the file. All from the command line */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define MXINTV 0x7FFFFFFF /* max int value */
#define ARBSZ 128
#define NPER 200 // num periods
typedef struct
{
char id[4]; // should always contain "RIFF"
int glen; // general length: total file length minus 8, could because the types so far seen (id and glen itself) are actually 8 bytes
char fstr[8]; // format string should be "WAVEfmt ": actually two 4chartypes here.
int fmtnum; // format number 16 for PCM format
short pcmnum; // PCM number 1 for PCM format
short nchans; // num channels
int sampfq; // sampling frequency: CD quality is 44100, 48000 is also common.
int byps; // BYtes_Per_Second (aka, BlockAlign) = numchannels* bytes per sample*samplerate. stereo shorts at 44100 . should be 176k.
short bypc; // BYtes_Per_Capture, bipsamp/8 most probably. A capture is the same as a sample if mono, but half a sample if stereo. bypc usually 2, a short.
short bipsamp; // bits_per_sample: CD quality is 16.
char datastr[4]; // should always contain "data"
int byid; // BYtes_In_Data;
} wh_t; /* wav header type */
wh_t *hdr4chunk(int sfre, char nucha, int certainsz) /* a header for a file chunk of certain siez */
{
wh_t *wh=malloc(sizeof(wh_t));
strncpy(wh->id, "RIFF", 4);
strncpy(wh->fstr, "WAVEfmt ", 8);
strncpy(wh->datastr, "data", 4);
wh->fmtnum=16;
wh->pcmnum=1;
wh->nchans=nucha; /* fed in to function */
wh->sampfq=sfre; /* fed in to function */
wh->glen=certainsz-8;
wh->bipsamp=16;
wh->bypc=wh->bipsamp/8;
wh->byps=wh->nchans*wh->sampfq*wh->bypc;
wh->byid=wh->glen-36;
return wh;
}
int hdrchk(wh_t *inhdr)
{
/* OK .. we test what sort of header we have */
if ( inhdr->id[0] != 'R'
|| inhdr->id[1] != 'I'
|| inhdr->id[2] != 'F'
|| inhdr->id[3] != 'F' ) {
printf("ERROR: RIFF string problem\n");
return 1;
}
if ( inhdr->fstr[0] != 'W'
|| inhdr->fstr[1] != 'A'
|| inhdr->fstr[2] != 'V'
|| inhdr->fstr[3] != 'E'
|| inhdr->fstr[4] != 'f'
|| inhdr->fstr[5] != 'm'
|| inhdr->fstr[6] != 't'
|| inhdr->fstr[7] != ' ' ) {
printf("ERROR: WAVEfmt string problem\n");
return 1;
}
if ( inhdr->datastr[0] != 'd'
|| inhdr->datastr[1] != 'a'
|| inhdr->datastr[2] != 't'
|| inhdr->datastr[3] != 'a' ) {
printf("WARNING: header \"data\" string does not come up\n");
return 1;
}
if ( inhdr->fmtnum != 16 ) {
printf("WARNING: fmtnum is %i, while it's better off being %i\n", inhdr->fmtnum, 16);
return 1;
}
if ( inhdr->pcmnum != 1 ) {
printf("WARNING: pcmnum is %i, while it's better off being %i\n", inhdr->pcmnum, 1);
return 1;
}
printf("There substantial evidence in the non-numerical fields of this file's header to think it is a wav file\n");
printf("glen: %i\n", inhdr->glen);
printf("byid: %i\n", inhdr->byid);
printf("nchans: %d\n", inhdr->nchans);
printf("sampfq: %i\n", inhdr->sampfq);
printf("byps: %i\n", inhdr->byps);
printf("bypc, bytes by capture (count of data in shorts): %d\n", inhdr->bypc);
printf("bipsamp: %d\n", inhdr->bipsamp);
if(inhdr->glen+8-44 == inhdr->byid)
printf("Good, \"byid\" (%i) is 36 bytes smaller than \"glen\" (%i).\n", inhdr->byid, inhdr->glen);
else {
printf("WARNING: glen (%i) and byid (%i)do not show prerequisite normal relation(diff is %i).\n", inhdr->glen, inhdr->byid, inhdr->glen-inhdr->byid);
}
// printf("Duration by glen is: %f\n", (float)(inhdr->glen+8-wh_tsz)/(inhdr->nchans*inhdr->sampfq*inhdr->byps));
printf("Duration by byps is: %f\n", (float)(inhdr->glen+8-44)/inhdr->byps);
if( (inhdr->bypc == inhdr->byps/inhdr->sampfq) && (inhdr->bypc == 2) )
printf("bypc complies with being 2 and matching byps/sampfq. Data values can therefore be recorded as signed shorts.\n");
return 0;
}
int main(int argc, char *argv[])
{
int i;
if(argc != 3) {
printf("Usage: sample a 256 val wavtable file Args: 1) Name of wavfile 2) which grouping of 256 vals (1-indexed)?\n");
exit(EXIT_FAILURE);
}
/* parse edit file in very simple terms, that means using scanf */
FILE *inwavfp;
inwavfp = fopen(argv[1],"rb");
if ( inwavfp == NULL ) {
fprintf(stderr,"Can't open input file %s", argv[1]);
exit(EXIT_FAILURE);
}
int grp=atoi(argv[2]);
// read header first
wh_t *inhdr=malloc(sizeof(wh_t));
if ( fread(inhdr, sizeof(wh_t), sizeof(char), inwavfp) < 1 ) {
printf("Can't read file header\n");
exit(EXIT_FAILURE);
}
int point=grp*512; //from this onwards, data to left out.
char *bf=malloc(point);
fseek(inwavfp, 44+512*(grp-1), SEEK_SET);
if ( fread(bf, point, sizeof(char), inwavfp) < 1 ) { /* Yup! we slurp in the baby! */
printf("Sorry, trouble putting input file into array. Overshot maybe?\n");
exit(EXIT_FAILURE);
}
fclose(inwavfp);
/* now we'll modify the inhdr to reflect what the out file will be */
inhdr->byid = 512*NPER;
inhdr->glen = 36+inhdr->byid;
/* now we prepare the output file */
FILE *outwavfp= fopen("wtout.wav","wb");
/* write we can already write out inhdr to there */
fwrite(inhdr, sizeof(char), 44, outwavfp);
/* now we want to read in the the first files data into a buffer
the FILEptrs are already positioned perfectly */
for(i=0;i<NPER;++i)
fwrite(bf, sizeof(char), point, outwavfp); //file descriptor will moive up
fclose(outwavfp);
free(bf);
free(inhdr);
return 0;
}