common.h (7495B)
1 /* 2 * Copyright (C) 2013-2015 Intel Corporation 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 */ 15 16 #define TEMP_RECORD_FILE_NAME "/tmp/bat.wav.XXXXXX" 17 #define DEFAULT_DEV_NAME "default" 18 19 #define OPT_BASE 300 20 #define OPT_LOG (OPT_BASE + 1) 21 #define OPT_READFILE (OPT_BASE + 2) 22 #define OPT_SAVEPLAY (OPT_BASE + 3) 23 #define OPT_LOCAL (OPT_BASE + 4) 24 #define OPT_STANDALONE (OPT_BASE + 5) 25 #define OPT_ROUNDTRIPLATENCY (OPT_BASE + 6) 26 #define OPT_SNRTHD_DB (OPT_BASE + 7) 27 #define OPT_SNRTHD_PC (OPT_BASE + 8) 28 29 #define COMPOSE(a, b, c, d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) 30 #define WAV_RIFF COMPOSE('R', 'I', 'F', 'F') 31 #define WAV_WAVE COMPOSE('W', 'A', 'V', 'E') 32 #define WAV_FMT COMPOSE('f', 'm', 't', ' ') 33 #define WAV_DATA COMPOSE('d', 'a', 't', 'a') 34 #define WAV_FORMAT_PCM 1 /* PCM WAVE file encoding */ 35 36 #define MAX_CHANNELS 2 37 #define MIN_CHANNELS 1 38 #define MAX_PEAKS 10 39 #define MAX_FRAMES (10 * 1024 * 1024) 40 /* Given in ms */ 41 #define CAPTURE_DELAY 500 42 /* signal frequency should be less than samplerate * RATE_FACTOR */ 43 #define RATE_FACTOR 0.4 44 /* valid range of samplerate: (1 - RATE_RANGE, 1 + RATE_RANGE) * samplerate */ 45 #define RATE_RANGE 0.05 46 /* Given in us */ 47 #define MAX_BUFFERTIME 500000 48 /* devide factor, was 4, changed to 8 to remove reduce capture overrun */ 49 #define DIV_BUFFERTIME 8 50 /* margin to avoid sign inversion when generate sine wav */ 51 #define RANGE_FACTOR 0.95 52 #define MAX_BUFFERSIZE 200000 53 #define MIN_BUFFERSIZE 32 54 #define MAX_PERIODSIZE 200000 55 #define MIN_PERIODSIZE 32 56 /* default period size for tinyalsa */ 57 #define TINYALSA_PERIODSIZE 1024 58 59 #define LATENCY_TEST_NUMBER 5 60 #define LATENCY_TEST_TIME_LIMIT 25 61 #define DIV_BUFFERSIZE 2 62 63 #define EBATBASE 1000 64 #define ENOPEAK (EBATBASE + 1) 65 #define EONLYDC (EBATBASE + 2) 66 #define EBADPEAK (EBATBASE + 3) 67 68 #define DC_THRESHOLD 7.01 69 70 /* tolerance of detected peak = max (DELTA_HZ, DELTA_RATE * target_freq). 71 * If DELTA_RATE is too high, BAT may not be able to recognize negative result; 72 * if too low, BAT may be too sensitive and results in uncecessary failure. */ 73 #define DELTA_RATE 0.005 74 #define DELTA_HZ 1 75 76 #define FOUND_DC (1<<1) 77 #define FOUND_WRONG_PEAK (1<<0) 78 79 /* Truncate sample frames to (1 << N), for faster FFT analysis process. The 80 * valid range of N is (SHIFT_MIN, SHIFT_MAX). When N increases, the analysis 81 * will be more time-consuming, and the result will be more accurate. */ 82 #define SHIFT_MAX (sizeof(int) * 8 - 2) 83 #define SHIFT_MIN 8 84 85 /* Define SNR range in dB. 86 * if the noise is equal to signal, SNR = 0.0dB; 87 * if the noise is zero, SNR is limited by RIFF wav data width: 88 * 8 bit --> 20.0 * log10f (powf(2.0, 8.0)) = 48.16 dB 89 * 16 bit --> 20.0 * log10f (powf(2.0, 16.0)) = 96.33 dB 90 * 24 bit --> 20.0 * log10f (powf(2.0, 24.0)) = 144.49 dB 91 * 32 bit --> 20.0 * log10f (powf(2.0, 32.0)) = 192.66 dB 92 * so define the SNR range (0.0, 200.0) dB, value out of range is invalid. */ 93 #define SNR_DB_INVALID -1.0 94 #define SNR_DB_MIN 0.0 95 #define SNR_DB_MAX 200.0 96 97 static inline bool snr_is_valid(float db) 98 { 99 return (db > SNR_DB_MIN && db < SNR_DB_MAX); 100 } 101 102 struct wav_header { 103 unsigned int magic; /* 'RIFF' */ 104 unsigned int length; /* file len */ 105 unsigned int type; /* 'WAVE' */ 106 }; 107 108 struct wav_chunk_header { 109 unsigned int type; /* 'data' */ 110 unsigned int length; /* sample count */ 111 }; 112 113 struct wav_fmt { 114 unsigned int magic; /* 'FMT '*/ 115 unsigned int fmt_size; /* 16 or 18 */ 116 unsigned short format; /* see WAV_FMT_* */ 117 unsigned short channels; 118 unsigned int sample_rate; /* Frequency of sample */ 119 unsigned int bytes_p_second; 120 unsigned short blocks_align; /* sample size; 1 or 2 bytes */ 121 unsigned short sample_length; /* 8, 12 or 16 bit */ 122 }; 123 124 struct chunk_fmt { 125 unsigned short format; /* see WAV_FMT_* */ 126 unsigned short channels; 127 unsigned int sample_rate; /* Frequency of sample */ 128 unsigned int bytes_p_second; 129 unsigned short blocks_align; /* sample size; 1 or 2 bytes */ 130 unsigned short sample_length; /* 8, 12 or 16 bit */ 131 }; 132 133 struct wav_container { 134 struct wav_header header; 135 struct wav_fmt format; 136 struct wav_chunk_header chunk; 137 }; 138 139 struct bat; 140 141 enum _bat_pcm_format { 142 BAT_PCM_FORMAT_UNKNOWN = -1, 143 BAT_PCM_FORMAT_S16_LE = 0, 144 BAT_PCM_FORMAT_S32_LE, 145 BAT_PCM_FORMAT_U8, 146 BAT_PCM_FORMAT_S24_3LE, 147 BAT_PCM_FORMAT_MAX 148 }; 149 150 enum _bat_op_mode { 151 MODE_UNKNOWN = -1, 152 MODE_SINGLE = 0, 153 MODE_LOOPBACK, 154 MODE_LAST 155 }; 156 157 enum latency_state { 158 LATENCY_STATE_COMPLETE_FAILURE = -1, 159 LATENCY_STATE_COMPLETE_SUCCESS = 0, 160 LATENCY_STATE_MEASURE_FOR_1_SECOND, 161 LATENCY_STATE_PLAY_AND_LISTEN, 162 LATENCY_STATE_WAITING, 163 }; 164 165 struct pcm { 166 unsigned int card_tiny; 167 unsigned int device_tiny; 168 char *device; 169 char *file; 170 enum _bat_op_mode mode; 171 void *(*fct)(struct bat *); 172 }; 173 174 struct sin_generator; 175 176 struct sin_generator { 177 double state_real; 178 double state_imag; 179 double phasor_real; 180 double phasor_imag; 181 float frequency; 182 float sample_rate; 183 float magnitude; 184 }; 185 186 struct roundtrip_latency { 187 int number; 188 enum latency_state state; 189 float result[LATENCY_TEST_NUMBER]; 190 int final_result; 191 int samples; 192 float sum; 193 int threshold; 194 int error; 195 bool is_capturing; 196 bool is_playing; 197 bool xrun_error; 198 }; 199 200 struct noise_analyzer { 201 int nsamples; /* number of sample */ 202 float *source; /* single-tone to be analyzed */ 203 float *target; /* target single-tone as standard */ 204 float rms_tgt; /* rms of target single-tone */ 205 float snr_db; /* snr in dB */ 206 }; 207 208 struct bat { 209 unsigned int rate; /* sampling rate */ 210 int channels; /* nb of channels */ 211 int frames; /* nb of frames */ 212 int frame_size; /* size of frame */ 213 int sample_size; /* size of sample */ 214 enum _bat_pcm_format format; /* PCM format */ 215 int buffer_size; /* buffer size in frames */ 216 int period_size; /* period size in frames */ 217 218 float sigma_k; /* threshold for peak detection */ 219 float snr_thd_db; /* threshold for noise detection (dB) */ 220 float target_freq[MAX_CHANNELS]; 221 222 int sinus_duration; /* number of frames for playback */ 223 char *narg; /* argument string of duration */ 224 char *logarg; /* path name of log file */ 225 char *debugplay; /* path name to store playback signal */ 226 bool standalone; /* enable to bypass analysis */ 227 bool roundtriplatency; /* enable round trip latency */ 228 229 struct pcm playback; 230 struct pcm capture; 231 struct roundtrip_latency latency; 232 233 unsigned int periods_played; 234 unsigned int periods_total; 235 bool period_is_limited; 236 237 FILE *fp; 238 239 FILE *log; 240 FILE *err; 241 242 void (*convert_sample_to_float)(void *, float *, int); 243 void (*convert_float_to_sample)(float *, void *, int, int); 244 245 void *buf; /* PCM Buffer */ 246 247 bool local; /* true for internal test */ 248 }; 249 250 struct analyze { 251 void *buf; 252 float *in; 253 float *out; 254 float *mag; 255 }; 256 257 void prepare_wav_info(struct wav_container *, struct bat *); 258 int read_wav_header(struct bat *, char *, FILE *, bool); 259 int write_wav_header(FILE *, struct wav_container *, struct bat *); 260 int update_wav_header(struct bat *, FILE *, int); 261 int generate_input_data(struct bat *, void *, int, int);