blob: 50b9a99ae3bcb41fe3ba20e9081e52683c7dbd1c [file] [log] [blame]
Bill Coxca02d872010-11-02 15:10:52 -04001/* Sonic library
2 Copyright 2010
3 Bill Cox
4 This file is part of the Sonic Library.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
19
20/*
21This file supports read/write wave files.
22*/
23#include <stdlib.h>
24#include <limits.h>
25#include <sndfile.h>
26#include "wave.h"
27
28struct waveFileStruct {
29 SNDFILE *soundFile;
30 short *values;
31 int numValues;
32};
33
34/* Open the file for reading. Also determine it's sample rate. */
35waveFile openInputWaveFile(
36 char *fileName,
37 int *sampleRate)
38{
39 SF_INFO info;
40 SNDFILE *soundFile;
41 waveFile file;
42
43 info.format = 0;
44 soundFile = sf_open(fileName, SFM_READ, &info);
45 if(soundFile == NULL) {
46 fprintf(stderr, "Unable to open wave file %s: %s\n", fileName, sf_strerror(NULL));
47 return NULL;
48 }
49 file = (waveFile)calloc(1, sizeof(struct waveFileStruct));
50 file->soundFile = soundFile;
51 file->numValues = 42;
52 file->values = (short *)calloc(file->numValues, sizeof(short));
53 *sampleRate = info.samplerate;
54 printf("Frames = %ld, sample rate = %d, channels = %d, format = %d",
55 info.frames, info.samplerate, info.channels, info.format);
56 return file;
57}
58
59/* Open the file for reading. */
60waveFile openOutputWaveFile(
61 char *fileName,
62 int sampleRate)
63{
64 SF_INFO info;
65 SNDFILE *soundFile;
66 waveFile file;
67
68 info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
69 info.samplerate = sampleRate;
70 info.channels = 1;
71 soundFile = sf_open(fileName, SFM_WRITE, &info);
72 if(soundFile == NULL) {
73 fprintf(stderr, "Unable to open wave file %s: %s", fileName, sf_strerror(NULL));
74 return NULL;
75 }
76 file = (waveFile)calloc(1, sizeof(struct waveFileStruct));
77 file->soundFile = soundFile;
78 file->numValues = 42;
79 file->values = (short *)calloc(file->numValues, sizeof(short));
80 return file;
81}
82
83/* Close the sound file. */
84void closeWaveFile(
85 waveFile file)
86{
87 SNDFILE *soundFile = file->soundFile;
88
89 sf_close(soundFile);
90}
91
92/* Read from the wave file. */
93int readFromWaveFile(
94 waveFile file,
95 float *buffer,
96 int maxSamples)
97{
98 SNDFILE *soundFile = file->soundFile;
99 int samplesRead;
100 int i;
101
102 if(maxSamples > file->numValues) {
103 file->numValues = maxSamples;
104 file->values = (short *)realloc(file->values, maxSamples*sizeof(short));
105 }
106 samplesRead = sf_read_short(soundFile, file->values, maxSamples);
107 if(samplesRead <= 0) {
108 return 0;
109 }
110 for(i = 0; i < samplesRead; i++) {
111 buffer[i] = file->values[i]/32768.0;
112 }
113 return samplesRead;
114}
115
116/* Write to the wave file. */
117int writeToWaveFile(
118 waveFile file,
119 float *buffer,
120 int numSamples)
121{
122 SNDFILE *soundFile = file->soundFile;
123 int value;
124 int xValue, numWritten;
125
126 if(numSamples > file->numValues) {
127 file->numValues = numSamples*3/2;
128 file->values = (short *)realloc(file->values, file->numValues*sizeof(short));
129 }
130 for(xValue = 0; xValue < numSamples; xValue++) {
131 value = (int)(file->values[xValue]*32768.0 + 0.5);
132 if(value > SHRT_MAX) {
133 file->values[xValue] = SHRT_MAX;
134 } else if (value < SHRT_MIN) {
135 file->values[xValue] = SHRT_MIN;
136 } else {
137 file->values[xValue] = value;
138 }
139 }
140 numWritten = sf_write_short(soundFile, file->values, numSamples);
141 if(numWritten != numSamples) {
142 fprintf(stderr, "Unable to write wave file.\n");
143 return 0;
144 }
145 return 1;
146}