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

v2.0 python #33

Merged
merged 4 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/link-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: Check Markdown links
on:
workflow_dispatch:
push:
branches: [main]
branches: [ main ]
pull_request:
branches: [main, 'v[0-9]+.[0-9]+']
branches: [ main, 'v[0-9]+.[0-9]+' ]

jobs:
markdown-link-check:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-codestyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ name: Python Codestyle
on:
workflow_dispatch:
push:
branches: [main]
branches: [ main ]
paths:
- '**/*.py'
pull_request:
branches: [main, 'v[0-9]+.[0-9]+']
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- '**/*.py'

Expand Down
16 changes: 14 additions & 2 deletions .github/workflows/python-demos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ name: Python Demos
on:
workflow_dispatch:
push:
branches: [main]
branches: [ main ]
paths:
- '.github/workflows/python-demos.yml'
- 'demo/python/**'
- '!demo/python/README.md'
- 'resources/audio_samples/test.wav'
pull_request:
branches: [main, 'v[0-9]+.[0-9]+']
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- '.github/workflows/python-demos.yml'
- 'demo/python/**'
Expand Down Expand Up @@ -41,6 +41,12 @@ jobs:
- name: Pre-build dependencies
run: python -m pip install --upgrade pip

# ************** REMOVE AFTER RELEASE ********************
- name: Build binding
run: |
pip install wheel && cd ../../binding/python && python setup.py sdist bdist_wheel && pip install dist/pvkoala-2.0.0-py3-none-any.whl
# ********************************************************

- name: Install dependencies
run: pip install -r requirements.txt

Expand All @@ -61,6 +67,12 @@ jobs:
steps:
- uses: actions/checkout@v3

# ************** REMOVE AFTER RELEASE ********************
- name: Build binding
run: |
pip3 uninstall -y pvkoala && pip3 install wheel && cd ../../binding/python && python3 setup.py sdist bdist_wheel && pip3 install dist/pvkoala-2.0.0-py3-none-any.whl
# ********************************************************

- name: Install dependencies
run: pip3 install -r requirements.txt

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-perf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Python Performance
on:
workflow_dispatch:
push:
branches: [main]
branches: [ main ]
paths:
- '.github/workflows/python-perf.yml'
- 'binding/python/__init__.py'
Expand All @@ -18,7 +18,7 @@ on:
- 'lib/windows/**'
- 'resources/audio_samples/test.wav'
pull_request:
branches: [main, 'v[0-9]+.[0-9]+']
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- '.github/workflows/python-perf.yml'
- 'binding/python/__init__.py'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Python
on:
workflow_dispatch:
push:
branches: [main]
branches: [ main ]
paths:
- '.github/workflows/python.yml'
- 'binding/python/**'
Expand All @@ -17,7 +17,7 @@ on:
- 'resources/audio_samples/noise.wav'
- 'resources/audio_samples/test.wav'
pull_request:
branches: [main, 'v[0-9]+.[0-9]+']
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- '.github/workflows/python.yml'
- 'binding/python/**'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/spell-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: SpellCheck
on:
workflow_dispatch:
push:
branches: [main]
branches: [ main ]
pull_request:
branches: [main, 'v[0-9]+.[0-9]+']
branches: [ main, 'v[0-9]+.[0-9]+' ]

jobs:
spellcheck:
Expand Down
73 changes: 67 additions & 6 deletions binding/python/_koala.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,27 @@


class KoalaError(Exception):
pass
def __init__(self, message: str = '', message_stack: Sequence[str] = None):
super().__init__(message)

self._message = message
self._message_stack = list() if message_stack is None else message_stack

def __str__(self):
message = self._message
if len(self._message_stack) > 0:
message += ':'
for i in range(len(self._message_stack)):
message += '\n [%d] %s' % (i, self._message_stack[i])
return message

@property
def message(self) -> str:
return self._message

@property
def message_stack(self) -> Sequence[str]:
return self._message_stack


class KoalaMemoryError(KoalaError):
Expand Down Expand Up @@ -123,15 +143,34 @@ def __init__(

library = cdll.LoadLibrary(library_path)

set_sdk_func = library.pv_set_sdk
set_sdk_func.argtypes = [c_char_p]
set_sdk_func.restype = None

set_sdk_func('python'.encode('utf-8'))

self._get_error_stack_func = library.pv_get_error_stack
self._get_error_stack_func.argtypes = [POINTER(POINTER(c_char_p)), POINTER(c_int)]
self._get_error_stack_func.restype = self.PicovoiceStatuses

self._free_error_stack_func = library.pv_free_error_stack
self._free_error_stack_func.argtypes = [POINTER(c_char_p)]
self._free_error_stack_func.restype = None

init_func = library.pv_koala_init
init_func.argtypes = [c_char_p, c_char_p, POINTER(POINTER(self.CKoala))]
init_func.restype = self.PicovoiceStatuses

self._handle = POINTER(self.CKoala)()

status = init_func(access_key.encode(), model_path.encode(), byref(self._handle))
status = init_func(
access_key.encode(),
model_path.encode(),
byref(self._handle))
if status is not self.PicovoiceStatuses.SUCCESS:
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status]()
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status](
message='Initialization failed',
message_stack=self._get_error_stack())

self._delete_func = library.pv_koala_delete
self._delete_func.argtypes = [POINTER(self.CKoala)]
Expand All @@ -144,7 +183,10 @@ def __init__(
status = delay_sample_func(self._handle, delay_sample)
if status is not self.PicovoiceStatuses.SUCCESS:
self.delete()
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status]()
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status](
message='Failed to get delay samples',
message_stack=self._get_error_stack())

self._delay_sample = delay_sample.value

self._process_func = library.pv_koala_process
Expand Down Expand Up @@ -193,7 +235,9 @@ def process(self, pcm: Sequence[int]) -> Sequence[int]:

status = self._process_func(self._handle, pcm, enhanced_pcm)
if status is not self.PicovoiceStatuses.SUCCESS:
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status]()
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status](
message='Processing failed',
message_stack=self._get_error_stack())

# noinspection PyTypeChecker
return list(enhanced_pcm)
Expand All @@ -206,7 +250,9 @@ def reset(self) -> None:

status = self._reset_func(self._handle)
if status is not self.PicovoiceStatuses.SUCCESS:
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status]()
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status](
message='Reset failed',
message_stack=self._get_error_stack())

def delete(self) -> None:
"""Releases resources acquired by Koala."""
Expand Down Expand Up @@ -239,6 +285,21 @@ def version(self) -> str:

return self._version

def _get_error_stack(self) -> Sequence[str]:
message_stack_ref = POINTER(c_char_p)()
message_stack_depth = c_int()
status = self._get_error_stack_func(byref(message_stack_ref), byref(message_stack_depth))
if status is not self.PicovoiceStatuses.SUCCESS:
raise self._PICOVOICE_STATUS_TO_EXCEPTION[status](message='Unable to get Porcupine error state')

message_stack = list()
for i in range(message_stack_depth.value):
message_stack.append(message_stack_ref[i].decode('utf-8'))

self._free_error_stack_func(message_stack_ref)

return message_stack


__all__ = [
'Koala',
Expand Down
4 changes: 2 additions & 2 deletions binding/python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
shutil.copytree(
os.path.join(os.path.dirname(__file__), '../../lib', platform),
os.path.join(package_folder, 'lib', platform))
manifest_in += "recursive-include pvkoala/lib/ *\n"
manifest_in += "recursive-include pvkoala/lib *\n"

with open(os.path.join(os.path.dirname(__file__), 'MANIFEST.in'), 'w') as f:
f.write(manifest_in)
Expand All @@ -42,7 +42,7 @@

setuptools.setup(
name="pvkoala",
version="1.0.1",
version="2.0.0",
author="Picovoice",
author_email="[email protected]",
description="Koala Noise Suppression Engine.",
Expand Down
28 changes: 27 additions & 1 deletion binding/python/test_koala.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import wave
from typing import Optional, Sequence

from _koala import Koala
from _koala import Koala, KoalaError
from _util import default_library_path, default_model_path


Expand Down Expand Up @@ -111,6 +111,32 @@ def test_version(self) -> None:
self.assertIsInstance(version, str)
self.assertGreater(len(version), 0)

def test_message_stack(self):
relative_path = '../..'

error = None
try:
k = Koala(
access_key='invalid',
model_path=default_model_path(relative_path),
library_path=default_library_path(relative_path))
self.assertIsNone(k)
except KoalaError as e:
error = e.message_stack

self.assertIsNotNone(error)
self.assertGreater(len(error), 0)

try:
k = Koala(
access_key='invalid',
model_path=default_model_path(relative_path),
library_path=default_library_path(relative_path))
self.assertIsNone(k)
except KoalaError as e:
self.assertEqual(len(error), len(e.message_stack))
self.assertListEqual(list(error), list(e.message_stack))


if __name__ == '__main__':
parser = argparse.ArgumentParser()
Expand Down
3 changes: 1 addition & 2 deletions demo/python/koala_demo_mic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import contextlib
import math
import struct
import sys
import wave

from pvkoala import create, KoalaActivationLimitError
Expand Down Expand Up @@ -45,7 +44,7 @@ def main():
args = parser.parse_args()

if args.show_audio_devices:
for index, name in enumerate(PvRecorder.get_audio_devices()):
for index, name in enumerate(PvRecorder.get_available_devices()):
print('Device #%d: %s' % (index, name))
return

Expand Down
2 changes: 1 addition & 1 deletion demo/python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pvkoala==1.0.1
pvkoala==2.0.0
pvrecorder==1.2.1
4 changes: 2 additions & 2 deletions demo/python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@

setuptools.setup(
name="pvkoalademo",
version="1.0.3",
version="2.0.0",
author="Picovoice",
author_email="[email protected]",
description="Koala Noise Suppression Engine demos",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/Picovoice/koala",
packages=["pvkoalademo"],
install_requires=["pvkoala==1.0.1", "pvrecorder==1.2.1"],
install_requires=["pvkoala==2.0.0", "pvrecorder==1.2.1"],
include_package_data=True,
classifiers=[
"Development Status :: 5 - Production/Stable",
Expand Down