comparison libtest/wavwriter.c @ 7:634df6435e16

libtest: WAV reader and writer code from opencore-amr-0.1.6/test
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 19 Nov 2022 22:50:08 +0000
parents
children
comparison
equal deleted inserted replaced
6:b2255a5d0519 7:634df6435e16
1 /* ------------------------------------------------------------------
2 * Copyright (C) 2009 Martin Storsjo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18
19 #include "wavwriter.h"
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <stdint.h>
24
25 struct wav_writer {
26 FILE *wav;
27 int data_length;
28
29 int sample_rate;
30 int bits_per_sample;
31 int channels;
32 };
33
34 static void write_string(struct wav_writer* ww, const char *str) {
35 fputc(str[0], ww->wav);
36 fputc(str[1], ww->wav);
37 fputc(str[2], ww->wav);
38 fputc(str[3], ww->wav);
39 }
40
41 static void write_int32(struct wav_writer* ww, int value) {
42 fputc((value >> 0) & 0xff, ww->wav);
43 fputc((value >> 8) & 0xff, ww->wav);
44 fputc((value >> 16) & 0xff, ww->wav);
45 fputc((value >> 24) & 0xff, ww->wav);
46 }
47
48 static void write_int16(struct wav_writer* ww, int value) {
49 fputc((value >> 0) & 0xff, ww->wav);
50 fputc((value >> 8) & 0xff, ww->wav);
51 }
52
53 static void write_header(struct wav_writer* ww, int length) {
54 int bytes_per_frame, bytes_per_sec;
55 write_string(ww, "RIFF");
56 write_int32(ww, 4 + 8 + 16 + 8 + length);
57 write_string(ww, "WAVE");
58
59 write_string(ww, "fmt ");
60 write_int32(ww, 16);
61
62 bytes_per_frame = ww->bits_per_sample/8*ww->channels;
63 bytes_per_sec = bytes_per_frame*ww->sample_rate;
64 write_int16(ww, 1); // Format
65 write_int16(ww, ww->channels); // Channels
66 write_int32(ww, ww->sample_rate); // Samplerate
67 write_int32(ww, bytes_per_sec); // Bytes per sec
68 write_int16(ww, bytes_per_frame); // Bytes per frame
69 write_int16(ww, ww->bits_per_sample); // Bits per sample
70
71 write_string(ww, "data");
72 write_int32(ww, length);
73 }
74
75 void* wav_write_open(const char *filename, int sample_rate, int bits_per_sample, int channels) {
76 struct wav_writer* ww = (struct wav_writer*) malloc(sizeof(*ww));
77 memset(ww, 0, sizeof(*ww));
78 ww->wav = fopen(filename, "wb");
79 if (ww->wav == NULL) {
80 free(ww);
81 return NULL;
82 }
83 ww->data_length = 0;
84 ww->sample_rate = sample_rate;
85 ww->bits_per_sample = bits_per_sample;
86 ww->channels = channels;
87
88 write_header(ww, ww->data_length);
89 return ww;
90 }
91
92 void wav_write_close(void* obj) {
93 struct wav_writer* ww = (struct wav_writer*) obj;
94 if (ww->wav == NULL) {
95 free(ww);
96 return;
97 }
98 fseek(ww->wav, 0, SEEK_SET);
99 write_header(ww, ww->data_length);
100 fclose(ww->wav);
101 free(ww);
102 }
103
104 void wav_write_data(void* obj, const unsigned char* data, int length) {
105 struct wav_writer* ww = (struct wav_writer*) obj;
106 if (ww->wav == NULL)
107 return;
108 fwrite(data, length, 1, ww->wav);
109 ww->data_length += length;
110 }
111