1 /* 2 * Copyright (C) 2016 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #include <stdint.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <fcntl.h> 43 #include <unistd.h> 44 45 #include "wav_util.h" 46 #include "btstack_util.h" 47 48 static const uint8_t sine_uint8[] = { 49 0, 15, 31, 46, 61, 74, 86, 97, 107, 114, 50 120, 124, 126, 126, 124, 120, 114, 107, 97, 86, 51 74, 61, 46, 31, 15, 0, 241, 225, 210, 195, 52 182, 170, 159, 149, 142, 136, 132, 130, 130, 132, 53 136, 142, 149, 159, 170, 182, 195, 210, 225, 241, 54 }; 55 56 57 // input signal: pre-computed sine wave, 160 Hz at 16000 kHz 58 static const int16_t sine_int16[] = { 59 0, 2057, 4107, 6140, 8149, 10126, 12062, 13952, 15786, 17557, 60 19260, 20886, 22431, 23886, 25247, 26509, 27666, 28714, 29648, 30466, 61 31163, 31738, 32187, 32509, 32702, 32767, 32702, 32509, 32187, 31738, 62 31163, 30466, 29648, 28714, 27666, 26509, 25247, 23886, 22431, 20886, 63 19260, 17557, 15786, 13952, 12062, 10126, 8149, 6140, 4107, 2057, 64 0, -2057, -4107, -6140, -8149, -10126, -12062, -13952, -15786, -17557, 65 -19260, -20886, -22431, -23886, -25247, -26509, -27666, -28714, -29648, -30466, 66 -31163, -31738, -32187, -32509, -32702, -32767, -32702, -32509, -32187, -31738, 67 -31163, -30466, -29648, -28714, -27666, -26509, -25247, -23886, -22431, -20886, 68 -19260, -17557, -15786, -13952, -12062, -10126, -8149, -6140, -4107, -2057, 69 }; 70 71 static int phase = 0; 72 73 static int wav_reader_fd; 74 static int bytes_per_sample = 2; 75 76 /* Write wav file utils */ 77 typedef struct wav_writer_state { 78 FILE * wav_file; 79 int total_num_samples; 80 int num_channels; 81 int sampling_frequency; 82 int frame_count; 83 } wav_writer_state_t; 84 85 wav_writer_state_t wav_writer_state; 86 87 88 static void little_endian_fstore_16(FILE *wav_file, uint16_t value){ 89 uint8_t buf[2]; 90 little_endian_store_16(buf, 0, value); 91 fwrite(&buf, 1, 2, wav_file); 92 } 93 94 static void little_endian_fstore_32(FILE *wav_file, uint32_t value){ 95 uint8_t buf[4]; 96 little_endian_store_32(buf, 0, value); 97 fwrite(&buf, 1, 4, wav_file); 98 } 99 100 static ssize_t __read(int fd, void *buf, size_t count){ 101 ssize_t len, pos = 0; 102 103 while (count > 0) { 104 len = read(fd, (int8_t * )buf + pos, count); 105 if (len <= 0) 106 return pos; 107 108 count -= len; 109 pos += len; 110 } 111 return pos; 112 } 113 114 static void write_wav_header(FILE * wav_file, int total_num_samples, int num_channels, int sample_rate){ 115 unsigned int write_with_bytes_per_sample = 2; 116 /* write RIFF header */ 117 fwrite("RIFF", 1, 4, wav_file); 118 // num_samples = blocks * subbands 119 uint32_t data_bytes = (uint32_t) (write_with_bytes_per_sample * total_num_samples * num_channels); 120 little_endian_fstore_32(wav_file, data_bytes + 36); 121 fwrite("WAVE", 1, 4, wav_file); 122 123 int byte_rate = sample_rate * num_channels * write_with_bytes_per_sample; 124 int bits_per_sample = 8 * write_with_bytes_per_sample; 125 int block_align = num_channels * bits_per_sample; 126 int fmt_length = 16; 127 int fmt_format_tag = 1; // PCM 128 129 /* write fmt chunk */ 130 fwrite("fmt ", 1, 4, wav_file); 131 little_endian_fstore_32(wav_file, fmt_length); 132 little_endian_fstore_16(wav_file, fmt_format_tag); 133 little_endian_fstore_16(wav_file, num_channels); 134 little_endian_fstore_32(wav_file, sample_rate); 135 little_endian_fstore_32(wav_file, byte_rate); 136 little_endian_fstore_16(wav_file, block_align); 137 little_endian_fstore_16(wav_file, bits_per_sample); 138 139 /* write data chunk */ 140 fwrite("data", 1, 4, wav_file); 141 little_endian_fstore_32(wav_file, data_bytes); 142 } 143 144 int wav_writer_open(const char * filepath, int num_channels, int sampling_frequency){ 145 FILE * wav_file = fopen(filepath, "wb"); 146 if (!wav_file) return 1; 147 148 wav_writer_state.wav_file = wav_file; 149 wav_writer_state.frame_count = 0; 150 wav_writer_state.total_num_samples = 0; 151 wav_writer_state.num_channels = num_channels; 152 wav_writer_state.sampling_frequency = sampling_frequency; 153 write_wav_header(wav_writer_state.wav_file, 0, num_channels, sampling_frequency); 154 return 0; 155 } 156 157 int wav_writer_close(void){ 158 rewind(wav_writer_state.wav_file); 159 write_wav_header(wav_writer_state.wav_file, wav_writer_state.total_num_samples, 160 wav_writer_state.num_channels, wav_writer_state.sampling_frequency); 161 fclose(wav_writer_state.wav_file); 162 return 0; 163 } 164 165 int wav_writer_write_int8(int num_samples, int8_t * data){ 166 if (data == NULL) return 1; 167 int i = 0; 168 int8_t zero_byte = 0; 169 for (i=0; i<num_samples; i++){ 170 fwrite(&zero_byte, 1, 1, wav_writer_state.wav_file); 171 uint8_t byte_value = (uint8_t)data[i]; 172 fwrite(&byte_value, 1, 1, wav_writer_state.wav_file); 173 } 174 175 wav_writer_state.total_num_samples+=num_samples; 176 wav_writer_state.frame_count++; 177 return 0; 178 } 179 180 int wav_writer_write_int16(int num_samples, int16_t * data){ 181 if (data == NULL) return 1; 182 fwrite(data, num_samples, 2, wav_writer_state.wav_file); 183 184 wav_writer_state.total_num_samples+=num_samples; 185 wav_writer_state.frame_count++; 186 return 0; 187 } 188 189 int wav_reader_open(const char * filepath){ 190 wav_reader_fd = open(filepath, O_RDONLY); 191 if (!wav_reader_fd) { 192 printf("Can't open file %s", filepath); 193 return 1; 194 } 195 196 uint8_t buf[40]; 197 __read(wav_reader_fd, buf, sizeof(buf)); 198 199 int num_channels = little_endian_read_16(buf, 22); 200 int block_align = little_endian_read_16(buf, 32); 201 bytes_per_sample = block_align/num_channels; 202 if (bytes_per_sample > 2){ 203 bytes_per_sample = bytes_per_sample/8; 204 } 205 return 0; 206 } 207 208 int wav_reader_close(void){ 209 close(wav_reader_fd); 210 return 0; 211 } 212 213 // Wav data: 8bit is uint8_t; 16bit is int16 214 int wav_reader_read_int8(int num_samples, int8_t * data){ 215 if (!wav_reader_fd) return 1; 216 int i; 217 int bytes_read = 0; 218 219 for (i=0; i<num_samples; i++){ 220 if (bytes_per_sample == 2){ 221 uint8_t buf[2]; 222 bytes_read +=__read(wav_reader_fd, &buf, 2); 223 data[i] = buf[1]; 224 } else { 225 uint8_t buf[1]; 226 bytes_read +=__read(wav_reader_fd, &buf, 1); 227 data[i] = buf[0] + 128; 228 } 229 } 230 return bytes_read == num_samples*bytes_per_sample; 231 } 232 233 int wav_reader_read_int16(int num_samples, int16_t * data){ 234 if (!wav_reader_fd) return 1; 235 int i; 236 int bytes_read = 0; 237 for (i=0; i<num_samples; i++){ 238 uint8_t buf[2]; 239 bytes_read +=__read(wav_reader_fd, &buf, 2); 240 data[i] = little_endian_read_16(buf, 0); 241 } 242 return bytes_read == num_samples*bytes_per_sample; 243 } 244 245 void wav_synthesize_sine_wave_int8(int num_samples, int8_t * data){ 246 int i; 247 for (i=0; i<num_samples; i++){ 248 data[i] = (int8_t)sine_uint8[phase]; 249 phase++; 250 if (phase >= sizeof(sine_uint8)) phase = 0; 251 } 252 } 253 254 void wav_synthesize_sine_wave_int16(int num_samples, int16_t * data){ 255 int i; 256 for (i=0; i < num_samples; i++){ 257 data[i] = sine_int16[phase++]; 258 if (phase >= (sizeof(sine_int16) / sizeof(int16_t))){ 259 phase = 0; 260 } 261 } 262 } 263 264