1 /* wavbreaker - A tool to split a wave file up into multiple wave.
2 * Copyright (C) 2002 Timothy Robinson
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include <stdio.h>
20 #include <sys/stat.h>
21 #include "cdda.h"
22
23 unsigned long file_size;
24
25 int
cdda_read_header(const char * filename,SampleInfo * sampleInfo)26 cdda_read_header(const char *filename,
27 SampleInfo *sampleInfo)
28 {
29 struct stat statBuf;
30
31 if (stat(filename, &statBuf)) {
32 printf("error stat'ing %s\n", filename);
33 return -1;
34 }
35
36 file_size = statBuf.st_size;
37
38 sampleInfo->numBytes = statBuf.st_size;
39 sampleInfo->channels = 2;
40 sampleInfo->samplesPerSec = 44100;
41 sampleInfo->bitsPerSample = 16;
42 sampleInfo->avgBytesPerSec = sampleInfo->bitsPerSample/8 * sampleInfo->samplesPerSec * sampleInfo->channels;
43 sampleInfo->blockAlign = 4;
44
45 return 0;
46 }
47
48 int
cdda_read_sample(FILE * fp,unsigned char * buf,int buf_size,unsigned long start_pos)49 cdda_read_sample(FILE *fp,
50 unsigned char *buf,
51 int buf_size,
52 unsigned long start_pos)
53 {
54 int i = 0;
55 int ret;
56
57 if (fseek(fp, start_pos, SEEK_SET)) {
58 return -1;
59 }
60
61 if (start_pos > file_size) {
62 return -1;
63 }
64
65 ret = fread(buf, 1, buf_size, fp);
66
67 for (i = 0; i < ret / 4; i++) {
68 unsigned char tmp;
69
70 /* left channel */
71 tmp = buf[i*4+0];
72 buf[i*4+0] = buf[i*4+1];
73 buf[i*4+1] = tmp;
74
75 /* right channel */
76 tmp = buf[i*4+2];
77 buf[i*4+2] = buf[i*4+3];
78 buf[i*4+3] = tmp;
79 }
80
81 return ret;
82 }
83
84 int
cdda_write_file(FILE * fp,char * filename,int buf_size,unsigned long start_pos,unsigned long end_pos)85 cdda_write_file(FILE *fp,
86 char *filename,
87 int buf_size,
88 unsigned long start_pos,
89 unsigned long end_pos)
90 {
91 int ret;
92 FILE *new_fp;
93 unsigned long cur_pos;
94 unsigned char buf[buf_size];
95
96 if ((new_fp = fopen(filename, "wb")) == NULL) {
97 printf("error opening %s for writing\n", filename);
98 return -1;
99 }
100
101 cur_pos = start_pos;
102
103 if (fseek(fp, cur_pos, SEEK_SET)) {
104 fclose(new_fp);
105 return -1;
106 }
107
108 if (cur_pos > file_size) {
109 fclose(new_fp);
110 return -1;
111 }
112
113 /* DEBUG CODE START */
114
115 printf("start_pos: %lu\n", start_pos);
116 printf("end_pos: %lu\n", end_pos);
117 printf("cur_pos: %lu\n", cur_pos);
118
119 /* DEBUG CODE END */
120
121 if (cur_pos + buf_size > end_pos && end_pos != 0) {
122 buf_size = end_pos - cur_pos;
123 }
124 while ((ret = fread(buf, 1, buf_size, fp)) > 0 &&
125 (cur_pos < end_pos || end_pos == 0)) {
126
127 if ((fwrite(buf, 1, ret, new_fp)) < ret) {
128 printf("error writing to file %s\n", filename);
129 fclose(new_fp);
130 return -1;
131 }
132 cur_pos += ret;
133
134 if (cur_pos + buf_size > end_pos && end_pos != 0) {
135 buf_size = end_pos - cur_pos;
136 }
137 }
138
139 /* DEBUG CODE START */
140 printf("cur_pos: %lu\n", cur_pos);
141 printf("done writing - %s\n\n", filename);
142 /* DEBUG CODE END */
143
144 fclose(new_fp);
145 return ret;
146 }
147