Picovoice with hifiberry DAC+ADC Pro Not working - python-3.x

I am trying to run picovoice i.c.w. HiFiBerry DAC+ ADC Pro but I can't get it to work.
All works fine when I use an usb microphone though.
As an example I'm running cheetah_demo_mic.py
import argparse
from threading import Thread
from pvcheetah import *
from pvrecorder import PvRecorder
class Demo(Thread):
def __init__(
self,
access_key: str,
model_path: Optional[str],
library_path: Optional[str],
endpoint_duration_sec: float,
enable_automatic_punctuation: bool):
super(Demo, self).__init__()
self._access_key = access_key
self._model_path = model_path
self._library_path = library_path
self._endpoint_duration_sec = endpoint_duration_sec
self._enable_automatic_punctuation = enable_automatic_punctuation
self._is_recording = False
self._stop = False
def run(self):
self._is_recording = True
o = None
recorder = None
try:
o = create(
access_key=self._access_key,
library_path=self._library_path,
model_path=self._model_path,
endpoint_duration_sec=self._endpoint_duration_sec)
recorder = PvRecorder(device_index=-1, frame_length=o.frame_length)
recorder.start()
print('Cheetah version : %s' % o.version)
while True:
partial_transcript, is_endpoint = o.process(recorder.read())
print(partial_transcript, end='', flush=True)
if is_endpoint:
print(o.flush())
except KeyboardInterrupt:
pass
finally:
if recorder is not None:
recorder.stop()
if o is not None:
o.delete()
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--access_key', required=True)
parser.add_argument('--library_path', default=None)
parser.add_argument('--model_path', default=None)
parser.add_argument('--endpoint_duration_sec', type=float, default=1.)
parser.add_argument('--disable_automatic_punctuation', action='store_true')
args = parser.parse_args()
Demo(
access_key=args.access_key,
library_path=args.library_path,
model_path=args.model_path,
endpoint_duration_sec=args.endpoint_duration_sec,
enable_automatic_punctuation=not args.disable_automatic_punctuation).run()
if __name__ == '__main__':
main()
By default this script uses audio device -1 which is the default audio device.
When I run the script like it is above (audio device -1) I get the following warn every few seconds:
[WARN] Input device might be muted or volume level is set to 0.
When I run the script with audio device 0 (which should be the same device) the screen immediately fills with the following warn:
[WARN] Overflow - reader is not reading fast enough.
Output of arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: sndrpihifiberry [snd_rpi_hifiberry_dacplusadcpro], device 0: HiFiBerry DAC+ADC Pro HiFi multicodec-0 [HiFiBerry DAC+ADC Pro HiFi multicodec-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
amixer settings:
amixer -c 0 sset 'ADC Right Input' 'VINR1[SE]'
amixer -c 0 sset 'ADC Left Input' 'VINL1[SE]'
amixer -c 0 sset 'ADC Mic Bias' 'Mic Bias off'
amixer -c 0 sset 'ADC' 0.00dB
When I run:
arecord -d 10 -D hw:0,0 -f S16_LE -c 2 -r 48000 testfile.wav
it records without a problem, and the wav file contains the actual audio.
Please help!
There must be some sertting that can fix this.
Thanks!
Robert.

Related

RTSP video change with python scheduler

I have 2 RTSP streams, I would like to change between them each minute and I would like to write the result into the same file (streaming.m3u8) and I would like embed HTML video tag.
But the video change is not working.
import ffmpeg
import schedule
import time
def stream_1():
packet_size = 4096
process = (
ffmpeg
.input('rtsp://....')
.output('streaming.m3u8', hls_time=3, hls_wrap=10)
.run_async(pipe_stdout=True)
)
while process.poll() is None:
packet = process.stdout.read(packet_size)
try:
tcp_socket.send(packet)
except socket.error:
process.stdout.close()
process.wait()
break
def stream_2():
packet_size = 4096
process = (
ffmpeg
.input('rtsp://....')
.output('streaming.m3u8', hls_time=3, hls_wrap=10)
.run_async(pipe_stdout=True)
)
while process.poll() is None:
packet = process.stdout.read(packet_size)
try:
tcp_socket.send(packet)
except socket.error:
process.stdout.close()
process.wait()
break
schedule.every(1).minutes.do(stream_1)
schedule.every(2).minutes.do(stream_2)

How to make a function that breaks a while loop that recording audio?

I'm trying to make a python gui that has 2 buttons, one for recording audio and one to stop recording. the code runs on a raspberry pi 3 with a usb mic connected already.
I've done the recording button, and now I'm stuck on the stop recording button.
the recording button runs in a while loop and I need that the 'stop' button will simply stop the while loop and save the recording to a file.
from sense_hat import SenseHat
import time
import Tkinter
import ttk
import pyaudio
import wave
sense = SenseHat()
sense.clear()
snsui = Tkinter.Tk()
snsui.style = ttk.Style()
snsui.style.theme_use("classic")
snsui.geometry('130x150')
snsui.resizable(0,0)
#img = PhotoImage(file='/home/pi/sensehat/fav.ico')
#snsui.Tkinter.call('wm', 'iconphoto', root._w, img)
#snsui.iconbitmap(default = "/home/pi/sensehat/image.png")
snsui.title("Sensors UI")
snsui.configure(background='light gray')
snsui.style.configure("TButton", padding=6, relief="flat",
background="turquoise",fieldbackground="black", foreground='royal blue')
form_1 = pyaudio.paInt16 # 16-bit resolution
chans = 1 # 1 channel
samp_rate = 44100 # 44.1kHz sampling rate
chunk = 4096 # 2^12 samples for buffer
record_secs = 3 # seconds to record
dev_index = 2 # device index found by p.get_device_info_by_index(ii)
audio = pyaudio.PyAudio() # create pyaudio instantiation
# create pyaudio stream
stream = audio.open(format = form_1,rate = samp_rate,channels = chans, \
input_device_index = dev_index,input = True, \
frames_per_buffer=chunk)
recording = True
def record(recording,s,a,c,ch,sr):
if recording == False:
recording = True
print('start recording')
else:
recording = False
print('trying to stop')
frames = []
# loop through stream and append audio chunks to frame array
# ii in range(0,int((samp_rate/chunk)*record_secs)):
while recording:
data = stream.read(chunk)
frames.append(data)
print("finished recording")
# stop the stream, close it, and terminate the pyaudio instantiation
stream.stop_stream()
stream.close()
audio.terminate()
wav_output_filename = 'test1.wav' # name of .wav file
# save the audio frames as .wav file
wavefile = wave.open(wav_output_filename,'wb')
wavefile.setnchannels(chans)
wavefile.setsampwidth(audio.get_sample_size(form_1))
wavefile.setframerate(samp_rate)
wavefile.writeframes(b''.join(frames))
wavefile.close()
B_recording = ttk.Button(snsui, text =" Record ", command = record(recording,stream,audio,chunk,chans,samp_rate))
B_recording.pack()
snsui.mainloop()
You can create boolean flag which value is changed by stop button. Then just add if statement to your while loop, and break when the flag have desired value.

read MFRD522 data using raspberry pi and send this data by http(python3)

I'm working on a project and I want to use RFID as a position reference(when raspberry pi and MFRC522 read the data, send it to server and make sure where is the position or adjust position while RFID reader is fixed)
My code is below:
import RPi.GPIO as GPIO
import MFRC522
import signal
import socket
HOST = '192.168.11.48'
PORT = 9009
continue_reading = True
# Capture SIGINT for cleanup when the script is aborted
def end_read(signal,frame):
global continue_reading
print("Ctrl+C captured, ending read.")
continue_reading = False
GPIO.cleanup()
# Hook the SIGINT
signal.signal(signal.SIGINT, end_read)
# Create an object of the class MFRC522
MIFAREReader = MFRC522.MFRC522()
# Welcome message
print("Welcome to the MFRC522 data read example")
# This loop keeps checking for chips. If one is near it will get the UID and authenticate
with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as sock:
sock.connect((HOST,PORT))
#print("closing client")
while True:
while continue_reading:
# Scan for cards
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
# If a card is found
if status == MIFAREReader.MI_OK:
print("Card detected")
# Get the UID of the card
(status,uid) = MIFAREReader.MFRC522_Anticoll()
# If we have the UID, continue
if status == MIFAREReader.MI_OK:
# Print UID
print("Card read UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]))
# This is the default key for authentication
key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
# Select the scanned tag
MIFAREReader.MFRC522_SelectTag(uid)
# Authenticate
status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid)
data = "str(uid[0])"
msg = data
sock.sendall(msg.encode())
data = sock.recv(128)
print('date from Echo server is [%s]'%data.decode())
# Check if authenticated
if status == MIFAREReader.MI_OK:
MIFAREReader.MFRC522_Read(8)
MIFAREReader.MFRC522_StopCrypto1()
else:
print("Authentication error")
I am using echo server to make sure that it's working
code for echo server is:
import socketserver
HOST = ''
PORT = 9009
class MyTcpHandler(socketserver.BaseRequestHandler):
def handle(self):
print("[%s]conneted"%self.client_address[0])
try:
while True:
self.data = self.request.recv(1024)
if self.data.decode() == "/quit":
print('ended by user [%s]'%self.client_address[0])
return
print('[%s]'%self.data.decode())
self.request.sendall(self.data)
except Exceptions as e:
print(e)
def runServer():
print("starting echo server")
print("if you want to close echo server, click Ctrl+C")
try:
server = socketserver.TCPServer((HOST,PORT), MyTcpHandler)
server.serve_forever()
except KeyboardInterrupt:
print("--- closing server")
runServer()
I ran fist piece of code while the second one was running, but only result I got was -
Welcome to the MFRC522 data read example
Card detected
Card read UID:178,29,209,48
size:8.
Anyone had idea what I should change to make it work?
thanks

How to pause/interupt with keyboard

I'm using the following script to play all the WAV files in the current path. I will be modifying it to print the output of some text files. That part is easy.
Need to know how/where in the loop of playing the WAV files, where to add some code to pause/interupt the execution of the code with the keyboard.
#!/usr/bin/python3
import vlc
import time
import glob
wav_files = glob.glob("*.wav")
instance=vlc.Instance(["--no-sub-autodetect-file"])
# You should not recreate a player for each file, just reuse the same
# player
player=instance.media_player_new()
for wav in wav_files:
player.set_mrl(wav)
player.play()
playing = set([1,2,3,4])
time.sleep(5) #Give time to get going
duration = player.get_length() / 1000
mm, ss = divmod(duration, 60)
print("Playing", wav, "Length:", "%02d:%02d" % (mm,ss))
while True:
state = player.get_state()
if state not in playing:
break
continue
Steal the getch right out of vlc.py
I've added the windows option, as you didn't specify an OS.
#!/usr/bin/python3
import vlc
import time
import glob
import sys
import termios, tty
try:
from msvcrt import getch # try to import Windows version
except ImportError:
def getch(): # getchar(), getc(stdin) #PYCHOK flake
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
return ch
wav_files = glob.glob("*.wav")
print("Play List")
for f in wav_files:
print(f)
instance=vlc.Instance(["--no-sub-autodetect-file"])
# You should not recreate a player for each file, just reuse the same
# player
player=instance.media_player_new()
for wav in wav_files:
player.set_mrl(wav)
player.play()
playing = set([1,2,3,4])
time.sleep(1) #Give time to get going
duration = player.get_length() / 1000
mm, ss = divmod(duration, 60)
print("Playing", wav, "Length:", "%02d:%02d" % (mm,ss))
while True:
state = player.get_state()
if state not in playing:
break
k = getch()
if k in ["N","n"]:#Next
player.stop()
break
elif k in ["Q","q"]:#Quit
player.stop()
sys.exit()
break
elif k == " ":#Toggle Pause
player.pause()
else:
print("[Q - Quit, N - Next, Space - Pause]")
continue

Python webcam record giving lower fps than desired

I am using opencv(cv2) in python to record videos(only video required) from multiple webcams simultaneously. Though they are not synchronized they record at a constant framerate. The problems are
They record at 4fps when resolution is set to 1080p, while desired is 30fps. The cameras I am using support this. While previewing though the framerate is 30fps which leads me to believe I may be doing some thing wrong while recording. I am using threading as in imutils library to get the videos as suggested in this blog post.
Is there anyway to synchronize the different camera outputs(videos).
PC specs:
Intel i5 7thgen,
8gb ddr3 ram,
SSD harddrive.
The webcams I'm using are Genius 32200312100 WideCam F100 USB 2.0 WebCam.
I do not think these are a limitation as I've been monitoring the CPU and memory usage while recording.
Any help is appreciated and if any further information is required please feel free to ask.
I'm open to using any encodings that will not compromise the quality of the picture.
Edit: I'm posting the code below.
class VideoRecorder():
#Function that runs once when the VideoRecorder class is called.
def __init__(self,cam_id = 0):
#Initialize the camera and set its properties
self.cam_id = cam_id
self.framerate = 30
self.video_height = 720
self.video_width = 1280
self.cap = cv2.VideoCapture(self.cam_id)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT,self.video_height)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH,self.video_width)
self.cap.set(cv2.CAP_PROP_FPS,self.framerate)
# Grab a initial frame, It is to warm up the camera.
# This frame will not be used
temp1, temp2 = self.cap.read()
#Set the place where the file is to be stored
storage_path = "{Output_folder}"
file_name = datetime.datetime.now().strftime("%m%d%Y_%H%M%S")
file_name = "cam_" + str(self.cam_id) + "_" + file_name + ".avi"
self.file = os.path.join(storage_path,file_name)
#Initialize a videowriter object to save the recorded frames to a file
self.fourcc = cv2.VideoWriter_fourcc(*'H264')
self.out = cv2.VideoWriter(self.file,self.fourcc,self.framerate,
(self.video_width,self.video_height))
def record(self, timer = 10):
#Start a timer for the recording to see how long the recording should be
self.start_time = time.time()
#Start a frame counter to calculate the framerate at the end
self.frame_count = 0
#Run an loop for given time to get frames from camera and store them
while(self.cap.isOpened()):
tora1 = time.time()
ret, frame = self.cap.read()
print("Time for reading the frame",time.time()-tora1)
if ret == True:
tora2 = time.time()
self.out.write(frame)
print("Time for write",tora2-time.time())
self.frame_count += 1
else:
break
current_time = time.time()
self.elapsed_time = current_time - self.start_time
if(self.elapsed_time > timer):
self.stop()
break
#Start the recording in a thread
def start(self, timer):
video_thread = threading.Thread(target = self.record, args = (timer,))
#video_thread.daemon = True
video_thread.start()
#Print the fps and release all the objects
def stop(self):
print("Frame count: %d"%self.frame_count)
self.fps = self.frame_count/self.elapsed_time
print(self.elapsed_time)
print("fps: %f"%self.fps)
self.out.release()
self.cap.release()
print("Done")
if __name__ == "__main__":
#Giving which arguments to pass to the script form command line ans
#getting them in a args structure
ap = argparse.ArgumentParser()
ap.add_argument("-t", "--runtime", type = int, default = 10,
help = "TIme for which the videorecoder runs")
ap.add_argument("-id", "--cam_id", type=int, default= 0,
help="give camera id")
args = vars(ap.parse_args())
required_time = args["runtime"]
video_thread = []
for i in range(args["cam_id"]+1):
t = VideoRecorder(i)
video_thread.append(t)
t.start(required_time)

Resources