/
piRecordConf.py
executable file
·221 lines (194 loc) · 7.28 KB
/
piRecordConf.py
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
###############################################################################
# PiCorderConf.py - Raspberry Pi audio recorder configuration module
# Author: John Hnatt
# Copyright 2019. All Rights Reserved.
# 11/24/19 jhnatt original
# 11/26/19 jhnatt modify for Python 3
# 11/27/19 jhnatt add performance tuning and user preferences
###############################################################################
import alsaaudio
import logging
import configparser
# Constants
UI_PROTO = 0
UI_LED_DISPLAY = 1
UI_DEFAULT = UI_PROTO
# Prototype Hardware configuration
protoSwPin = 26 #GPIO 26
protoLedPin = 13 #GPIO 13
protoDebounce = 0.02 #debounce time = 20 ms
# File namimng configuration
outputDir = "../Recordings"
fileFormatStr = "%Y%m%d_%H%M%S"
fileTypeExt = ".wav"
#global record configuration variables. Initialize with default values.
recDevice = "default"
recChannels = 1
recRate = 44100
recFormat = alsaaudio.PCM_FORMAT_S16_LE
recPeriodSize = 160
recSampleWidth = 2
#Performance tuning
engineLoopPd = 0.001
swDebounceTime = 0.020
#User preferences
idleSeconds = 300.000
auditionTime = 3.00
#Config item display lists (exported to main which handles settings)
cfgItemDispList = ["Dev", "Chn", "Rat", "Fmt", "Per", "Wid"]
#Logging configuration
LOG_LVL_DBG = 15 #define higher than regular debug to keep from flooding with ALSA debug messages
logLevel = LOG_LVL_DBG
logFile = './piRecord.log'
logFormat = '%(asctime)s %(levelname)s: %(message)s'
logging.basicConfig(filename=logFile,format=logFormat,level=logLevel)
#Create configuration parser object
recConfig = configparser.RawConfigParser()
###############################################################################
# Function Name:
# printConfig
# Description:
# prints the current configuration
# Parameters:
# none
# Return value:
# 0
###############################################################################
def printConfig():
global recConfig
global recDevice, recChannels, recRate, recFormat, recPeriodSize, recSampleWidth
global swDebounceTime, engineLoopPd, idleSeconds, auditionTime
print ("Current Recording Config:")
print (" recDevice = ", recDevice)
print (" recChannels = ", recChannels)
print (" recRate = ", recRate)
print (" recFormat = ", recFormat)
print (" recPeriodSize = ", recPeriodSize)
print (" recSampleWidth = ", recSampleWidth)
print ("Performance Tuning:")
print (" swDebounceTime: ", swDebounceTime)
print (" engineLoopPd: ", engineLoopPd)
print ("User Preferences: ")
print (" idleSeconds", idleSeconds)
print (" auditionTime", auditionTime)
print (" ")
print ("to change a setting, edit piRecord.cfg and restart piRecord")
return 0
###############################################################################
# Function Name:
# getRecDevice
# Description:
# this function obtains the list of available devices from ALSA and finds the
# one matching the configured device.
# Parameters:
# none
# Return value:
# device name, else null if device not found.
###############################################################################
def getRecDevice():
devList = alsaaudio.pcms(alsaaudio.PCM_CAPTURE)
for dev in devList:
if recDevice in dev:
return dev
return 'null'
###############################################################################
# Function Name:
# getRecFormat
# Description:
# this function converts the individual format parameters into the single
# constant used by the ALSA library.
# Parameters:
# numBits: number of bits (8, 16, or 32)
# signed: True = signed, False = unsigned
# byteOrder: LE = little endian, BE = big endian
# Return value:
# the resulting constant.
###############################################################################
def getRecFormat(numBits, signed, byteOrder):
if signed == False:
if byteOrder == 'BE':
if numBits == 8:
fmt = alsaaudio.PCM_FORMAT_U8
elif numBits == 24:
fmt = alsaaudio.PCM_FORMAT_U24_BE
elif numBits == 32:
fmt = alsaaudio.PCM_FORMAT_U32_BE
else:
fmt = alsaaudio.PCM_FORMAT_U16_BE
else:
if numBits == 8:
fmt = alsaaudio.PCM_FORMAT_U8
elif numBits == 24:
fmt = alsaaudio.PCM_FORMAT_U24_LE
elif numBits == 32:
fmt = alsaaudio.PCM_FORMAT_U32_LE
else:
fmt = alsaaudio.PCM_FORMAT_U16_LE
else:
if byteOrder == 'BE':
if numBits == 8:
fmt = alsaaudio.PCM_FORMAT_S8
elif numBits == 24:
fmt = alsaaudio.PCM_FORMAT_S24_BE
elif numBits == 32:
fmt = alsaaudio.PCM_FORMAT_S32_BE
else:
fmt = alsaaudio.PCM_FORMAT_S16_BE
else:
if numBits == 8:
fmt = alsaaudio.PCM_FORMAT_S8
elif numBits == 24:
fmt = alsaaudio.PCM_FORMAT_S24_LE
elif numBits == 32:
fmt = alsaaudio.PCM_FORMAT_S32_LE
else:
fmt = alsaaudio.PCM_FORMAT_S16_LE
return fmt
###############################################################################
# Function Name:
# getRecDevDevConfig
# Description:
# this function obtains the configuration from the config file piRecord.cfg.
# Parameters:
# none
# Return value:
# 0
###############################################################################
def getRecDevConfig():
global recConfig
global recDevice, recChannels, recRate, recFormat, recPeriodSize, recSampleWidth
global swDebounceTime, engineLoopPd, idleSeconds, auditionTime
recConfig.read('piRecord.cfg')
#get recording configuration
recDevice = recConfig.get('recDevice', 'devName')
recChannels = recConfig.getint('recDevice', 'numChan')
recRate = recConfig.getint('recDevice', 'rate')
recFormat = getRecFormat(recConfig.getint('recDevice', 'numBits'), recConfig.getboolean('recDevice', 'signed'), recConfig.get('recDevice', 'byteOrder'))
recPeriodSize = recConfig.getint('recDevice', 'periodSize')
recSampleWidth = recConfig.getint('recDevice', 'sampleWidth')
#get performance tunings:
swDebounceTime = recConfig.getfloat('performanceTuning', 'swDebounceTime')
engineLoopPd = recConfig.getfloat('performanceTuning', 'engineLoopPd')
#get user preferences:
idleSeconds = recConfig.getfloat('userPreferences', 'idleSeconds')
auditionTime = recConfig.getfloat('userPreferences', 'auditionTime')
return 0
###############################################################################
# Function Name:
# __main__to be
# Description:
# the main function for the piRecordCfg module. Allows module to run standalone
# from command line to display configuration.
# Parameters:
# none
# Return value:
# none
###############################################################################
if __name__ == "__main__":
getRecDevConfig()
printConfig()
print ("\nList of available record devices:")
devList = alsaaudio.pcms(alsaaudio.PCM_CAPTURE)
for dev in devList:
print (" ", dev)
print ("Record device in use = ", getRecDevice())