PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
main.c
1#include <stdio.h>
2#include <errno.h>
3#include <string.h>
4#include <ctype.h>
5#include <math.h>
6
7#define VERSION "1.2"
8
9extern int adpcm_encode(FILE* fp, FILE* sad, int offset, int sample_len, int flag_loop, int bytes_per_sample);
10
11enum{ monoF = (1 << 0), stereo = (1 << 1), loopF = (1 << 2) } sad_flag;
12
14 char id[4]; //"APCM"
15 unsigned char version;
16 unsigned char channels;
17 unsigned char loop;
18 unsigned char reserved;
19 unsigned int pitch;
20 unsigned int samples;
21};
22
23static int ConvertFile(const char *InputFile, const char *OutputFile, int flag_loop){
24 FILE *fp, *sad;
25 int sample_freq, sample_len, result;
26 char s[4];
27 int chunk_data;
28 short e;
29 char channels;
30 char bytes_per_sample;
32
33 result=0;
34 if ( (fp = fopen(InputFile, "rb" )) != NULL )
35 {
36 if (fread( s, 1, 4, fp )!=4 || strncmp( s, "RIFF", 4 ) )
37 {
38 printf( "Error: Not a WAVE-file (\"RIFF\" identifier not found)\n" );
39 result=-3;
40 goto InputFileIOEnd;
41 }
42
43 fseek( fp, 8, SEEK_SET );
44
45 if (fread( s, 1, 4, fp )!=4 || strncmp( s, "WAVE", 4 ) )
46 {
47 printf( "Error: Not a WAVE-file (\"WAVE\" identifier not found)\n" );
48 result=-3;
49 goto InputFileIOEnd;
50 }
51
52 fseek( fp, 8 + 4, SEEK_SET );
53
54 if (fread( s, 1, 4, fp )!=4 || strncmp( s, "fmt", 3 ) )
55 {
56 printf( "Error: Not a WAVE-file (\"fmt\" chunk not found)\n" );
57 result=-3;
58 goto InputFileIOEnd;
59 }
60
61 if(fread( &chunk_data, 4, 1, fp )==1){
62 chunk_data += ftell( fp );
63
64 if (fread( &e, 2, 1, fp )!=1 || e != 1 )
65 {
66 printf( "Error: No PCM data in WAVE-file\n" );
67 result=-4;
68 goto InputFileIOEnd;
69 }
70 }
71 else{
72 printf( "Error: can't read CHUNK DATA in WAVE-file\n" );
73 result=-4;
74 goto InputFileIOEnd;
75 }
76
77 if (fread( &e, 2, 1, fp )!=1 || ((e != 1) && (e != 2)))
78 {
79 printf( "Error: WAVE file must be MONO or STEREO (max 2 channels)\n" );
80 result=-5;
81 goto InputFileIOEnd;
82 }
83
84 channels = e;
85
86 if(fread( &sample_freq, 4, 1, fp )==1){
87 fseek( fp, 4 + 2, SEEK_CUR );
88 if (fread( &e, 2, 1, fp )!=1 || (e != 8 && e != 16) )
89 {
90 printf( "Error: WAVE-file must 8 or 16 bit\n" );
91 result=-6;
92 goto InputFileIOEnd;
93 }
94 bytes_per_sample = e / 8;
95 }
96 else{
97 printf("Error: Can't read SAMPLE FREQUENCY in WAVE-file\n");
98 result=-6;
99 goto InputFileIOEnd;
100 }
101
102 fseek( fp, chunk_data, SEEK_SET );
103 if(fread( s, 1, 4, fp )==4){
104 // Skip 'fact' and possibly other chunks
105 while(strncmp( s, "data", 4 ))
106 {
107 if(fread( &chunk_data, 4, 1, fp )==1){
108 chunk_data += ftell( fp );
109 fseek( fp, chunk_data, SEEK_SET );
110 if(fread( s, 1, 4, fp )!=4){
111 printf("Error: Read error in WAVE-file\n");
112 result=-6;
113 goto InputFileIOEnd;
114 }
115 }
116 else{
117 printf("Error: Read error in WAVE-file\n");
118 result=-6;
119 goto InputFileIOEnd;
120 }
121 }
122 }
123 else{
124 printf("Error: Read error in WAVE-file\n");
125 result=-6;
126 goto InputFileIOEnd;
127 }
128
129 if(fread( &sample_len, 4, 1, fp )==1){
130 sample_len /= (channels*bytes_per_sample);
131 }
132 else{
133 printf("Error: Can't read SAMPLE LENGTH in WAVE-file\n");
134 result=-6;
135 goto InputFileIOEnd;
136 }
137
138 if ( (sad = fopen(OutputFile, "wb" )) != NULL )
139 {
140 AdpcmHeader = (struct AdpcmHeader)
141 {
142 .id="APCM",
143 .version=1,
144 .channels=channels,
145 .loop=flag_loop,
146 .reserved=0,
147 .pitch=(sample_freq*4096)/48000, // pitch, to encode for PS1 change 48000 to 44100
148 .samples=sample_len
149 };
150 fwrite(&AdpcmHeader, sizeof(AdpcmHeader), 1, sad);
151
152 if(channels == 1)
153 {
154 result=adpcm_encode(fp, sad, 0, sample_len, flag_loop, bytes_per_sample);
155 }
156 else
157 {
158 int data_offset = ftell(fp);
159
160 // Encode left
161 if((result=adpcm_encode(fp, sad, bytes_per_sample, sample_len, flag_loop, bytes_per_sample))==0){
162 fseek(fp, data_offset+bytes_per_sample, SEEK_SET);
163 // Encode right
164 result=adpcm_encode(fp, sad, bytes_per_sample, sample_len, flag_loop, bytes_per_sample);
165 }
166 }
167
168 fclose(sad);
169 }
170 else
171 {
172 printf( "Error: Can't write output file %s\n", OutputFile);
173 result=EIO;
174 }
175
176InputFileIOEnd:
177 fclose(fp);
178 }
179 else
180 {
181 printf( "Error: Can't open %s\n", InputFile);
182 result=ENOENT;
183 }
184
185 return result;
186}
187
188int main( int argc, char *argv[] )
189{
190 int result;
191
192 if( argc == 4)
193 {
194 if( strncmp( argv[1], "-L", 2 ) )
195 {
196 printf("Error: Option '%s' not recognized\n", argv[1]);
197 result=EINVAL;
198 }
199 else
200 {
201 result=ConvertFile(argv[2], argv[3], 1);
202 }
203 }
204 else if(argc == 3)
205 {
206 result=ConvertFile(argv[1], argv[2], 0);
207 }
208 else
209 {
210 printf( "ADPCM Encoder %s\n"
211 "Usage: sadenc [-L] <input wave> <output sad>\n"
212 "Options:\n"
213 " -L Loop\n", VERSION);
214 result=EINVAL;
215 }
216
217 return result;
218}
#define ENOENT
Definition errno.h:23
#define EINVAL
Definition errno.h:63
#define EIO
Definition errno.h:29