1e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber/*
2e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
4e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * you may not use this file except in compliance with the License.
6e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * You may obtain a copy of the License at
7e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
8e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
10e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Unless required by applicable law or agreed to in writing, software
11e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * See the License for the specific language governing permissions and
14e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * limitations under the License.
15e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber */
16e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
17e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#ifndef ANDROID_WAVEWRITER_H_
18e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
19e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#define ANDROID_WAVEWRITER_H_
20e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
21e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android {
22e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
23e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass WaveWriter {
24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic:
25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    WaveWriter(const char *filename,
26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber               uint16_t num_channels, uint32_t sampling_rate)
27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        : mFile(fopen(filename, "wb")),
28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber          mTotalBytes(0) {
29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        fwrite("RIFFxxxxWAVEfmt \x10\x00\x00\x00\x01\x00", 1, 22, mFile);
30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u16(num_channels);
31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u32(sampling_rate);
32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u32(sampling_rate * num_channels * 2);
33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u16(num_channels * 2);
34e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u16(16);
35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        fwrite("dataxxxx", 1, 8, mFile);
36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    ~WaveWriter() {
39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        fseek(mFile, 40, SEEK_SET);
40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u32(mTotalBytes);
41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        fseek(mFile, 4, SEEK_SET);
43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u32(36 + mTotalBytes);
44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        fclose(mFile);
46e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mFile = NULL;
47e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
48e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
49e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    void Append(const void *data, size_t size) {
50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        fwrite(data, 1, size, mFile);
51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mTotalBytes += size;
52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate:
55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    void write_u16(uint16_t x) {
56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        fputc(x & 0xff, mFile);
57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        fputc(x >> 8, mFile);
58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
59e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
60e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    void write_u32(uint32_t x) {
61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u16(x & 0xffff);
62e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        write_u16(x >> 16);
63e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    FILE *mFile;
66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t mTotalBytes;
67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber};
68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}  // namespace android
70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#endif  // ANDROID_WAVEWRITER_H_
72