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