forked from wb2osz/direwolf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
audio_stats.c
182 lines (151 loc) · 5.3 KB
/
audio_stats.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//
// This file is part of Dire Wolf, an amateur radio packet TNC.
//
// Copyright (C) 2015 John Langner, WB2OSZ
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
/*------------------------------------------------------------------
*
* Module: audio_stats.c
*
* Purpose: Print statistics for audio input stream.
*
* A common complaint is that there is no indication of
* audio input level until a packet is received correctly.
* That's true for the Windows version but the Linux version
* prints something like this each 100 seconds:
*
* ADEVICE0: Sample rate approx. 44.1 k, 0 errors, receive audio level CH0 73
*
* Some complain about the clutter but it has been a useful
* troubleshooting tool. In the earlier RPi days, the sample
* rate was quite low due to a device driver issue.
* Using a USB hub on the RPi also caused audio problems.
* One adapter, that I tried, produces samples at the
* right rate but all the samples are 0.
*
* Here we pull the code out of the Linux version of audio.c
* so we have a common function for all the platforms.
*
* We also add a command line option to adjust the time
* between reports or turn them off entirely.
*
* Revisions: This is new in version 1.3.
*
*---------------------------------------------------------------*/
#include "direwolf.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <time.h>
#include "audio_stats.h"
#include "textcolor.h"
#include "dtime_now.h"
#include "demod.h" /* for alevel_t & demod_get_audio_level() */
/*------------------------------------------------------------------
*
* Name: audio_stats
*
* Purpose: Add sample count from one buffer to the statistics.
* Print if specified amount of time has passed.
*
* Inputs: adev - Audio device number: 0, 1, ..., MAX_ADEVS-1
*
nchan - Number of channels for this device, 1 or 2.
*
* nsamp - How many audio samples were read.
*
* interval - How many seconds between reports.
* 0 to turn off.
*
* Returns: none
*
* Description: ...
*
*----------------------------------------------------------------*/
void audio_stats (int adev, int nchan, int nsamp, int interval)
{
/* Gather numbers for read from audio device. */
static time_t last_time[MAX_ADEVS] = { 0, 0, 0 };
time_t this_time[MAX_ADEVS];
static int sample_count[MAX_ADEVS];
static int error_count[MAX_ADEVS];
static int suppress_first[MAX_ADEVS];
if (interval <= 0) {
return;
}
assert (adev >= 0 && adev < MAX_ADEVS);
/*
* Print information about the sample rate as a troubleshooting aid.
* I've never seen an issue with Windows or x86 Linux but the Raspberry Pi
* has a very troublesome audio input system where many samples got lost.
*
* While we are at it we can also print the current audio level(s) providing
* more clues if nothing is being decoded.
*/
if (last_time[adev] == 0) {
last_time[adev] = time(NULL);
sample_count[adev] = 0;
error_count[adev] = 0;
suppress_first[adev] = 1;
/* suppressing the first one could mean a rather */
/* long wait for the first message. We make the */
/* first collection interval 3 seconds. */
last_time[adev] -= (interval - 3);
}
else {
if (nsamp > 0) {
sample_count[adev] += nsamp;
}
else {
error_count[adev]++;
}
this_time[adev] = time(NULL);
if (this_time[adev] >= last_time[adev] + interval) {
if (suppress_first[adev]) {
/* The issue we had is that the first time the rate */
/* would be off considerably because we didn't start */
/* on a second boundary. So we will suppress printing */
/* of the first one. */
suppress_first[adev] = 0;
}
else {
float ave_rate = (sample_count[adev] / 1000.0) / interval;
text_color_set(DW_COLOR_DEBUG);
if (nchan > 1) {
int ch0 = ADEVFIRSTCHAN(adev);
alevel_t alevel0 = demod_get_audio_level(ch0,0);
int ch1 = ADEVFIRSTCHAN(adev) + 1;
alevel_t alevel1 = demod_get_audio_level(ch1,0);
dw_printf ("\nADEVICE%d: Sample rate approx. %.1f k, %d errors, receive audio levels CH%d %d, CH%d %d\n\n",
adev, ave_rate, error_count[adev], ch0, alevel0.rec, ch1, alevel1.rec);
}
else {
int ch0 = ADEVFIRSTCHAN(adev);
alevel_t alevel0 = demod_get_audio_level(ch0,0);
dw_printf ("\nADEVICE%d: Sample rate approx. %.1f k, %d errors, receive audio level CH%d %d\n\n",
adev, ave_rate, error_count[adev], ch0, alevel0.rec);
}
}
last_time[adev] = this_time[adev];
sample_count[adev] = 0;
error_count[adev] = 0;
}
}
} /* end audio_stats.c */