Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added non-blocking version of python demo #32

Merged
merged 3 commits into from
Jun 15, 2018

Conversation

fquirin
Copy link
Contributor

@fquirin fquirin commented Jun 13, 2018

see:
#27

Starting from the input-buffer overflow issue I've encountered on my raspberry Pi zero I've changed the demo to run pyaudio in non-blocking mode (basically it does a callback to the execution function instead of waiting for processing to finish). It also gives you the chance to add some custom actions to the callback which always crashed the program in the blocking version.

@kenarsa
Copy link
Member

kenarsa commented Jun 13, 2018

This is amazing. I think the community would love this as it is extremely useful for smaller devices such as RPi zero. I have few minor comments and only one major one. All can be addressed easily :)

Let read through my comments and address if necessary. Happy to discuss :)

@fquirin
Copy link
Contributor Author

fquirin commented Jun 14, 2018

Happy to address your comments, but ... I can't find them 😅 Am I missing something?

input=True,
frames_per_buffer=frame_length,
input_device_index=self._input_device_index,
stream_callback=_audio_callback)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please replace the tabs with space?

"""

num_keywords = len(self._keyword_file_paths)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove extra space here

print('[%s] detected keyword #%d' % (str(datetime.now()), result))
# or add it here if you use multiple keywords

return (None, pyaudio.paContinue)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can safely remove the parentheses here :)

result = porcupine.process(pcm)
if num_keywords == 1 and result:
print('[%s] detected keyword' % str(datetime.now()))
# add you own code execution here ... it will not block the recognition
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor typo: you -> your

sample_rate = porcupine.sample_rate
num_channels = 1
audio_format = pyaudio.paInt16
if not self.frame_length:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if checking for None explicitly maybe we can do "if self.frame_length is None:"?

self._model_file_path = model_file_path
self._keyword_file_paths = keyword_file_paths
self._sensitivity = float(sensitivity)
self.frame_length = frame_length
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make it a protected member (self.frame_length -> self._frame_length) as it will not be used outside of class.

sensitivities=[self._sensitivity] * num_keywords)

pa = pyaudio.PyAudio()
sample_rate = porcupine.sample_rate
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this above try as you are using it in finally statement as well.


num_keywords = len(self._keyword_file_paths)

def _audio_callback(in_data, frame_count, time_info, status):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be that I don't understand the unblocking API well ...

But the frame_count here needs to be set exactly to porcupine.frame_length otherwise the interface won't work. If the frame_count is larger then we only read the first part of it and then throw the rest. Therefore we won't be able to detect keywords. I actually tried with 4096 and I can't make it work. Could you please confirm? Also if it is smaller then we never process audio.

I think for non_blocking we need to remove the option to set frame_length and just set it to porcupine.frame_length internally in the class.
Let me know what you think :)

@kenarsa
Copy link
Member

kenarsa commented Jun 14, 2018

Sorry, my mistake. Forgot to click on submit.

@fquirin
Copy link
Contributor Author

fquirin commented Jun 14, 2018

I've addressed all the comments and removed the frame_length parameter. I think you are right, it will not work anyway if it is not the same as inside porcupine. I put it in for testing, but as far as I remember changing the value resulted in no keyword detection all the time and then I just left it at the default value 🙈 I wasn't entirely sure what happens inside porcupine though and thought it might be useful at some point. Guess not ^^.

@kenarsa
Copy link
Member

kenarsa commented Jun 15, 2018

Thanks a lot :)

@kenarsa kenarsa merged commit a08ab1e into Picovoice:master Jun 15, 2018
kenarsa pushed a commit that referenced this pull request Aug 31, 2019
* added non-blocking version of python demo

see:
#27

* addressed most comments of pull request

* removed argument frame_length

Former-commit-id: a08ab1e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants