sbvoicedb


Namesbvoicedb JSON
Version 0.3.0 PyPI version JSON
download
home_pageNone
SummarySaarbrueken Voice Database Downloader and Reader
upload_time2025-09-13 02:13:05
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseGPL-2.0 License
keywords multimedia
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            `sbvoicedb`: Saarbrueken Voice Database Reader module
======================================================

|pypi| |status| |pyver| |license|

.. |pypi| image:: https://img.shields.io/pypi/v/sbvoicedb
  :alt: PyPI
.. |status| image:: https://img.shields.io/pypi/status/sbvoicedb
  :alt: PyPI - Status
.. |pyver| image:: https://img.shields.io/pypi/pyversions/sbvoicedb
  :alt: PyPI - Python Version
.. |license| image:: https://img.shields.io/github/license/tikuma-lsuhsc/python-sbvoicedb
  :alt: GitHub


This Python module provides capability to download and organize Saarbrücker Stimmdatenbank 
(Saarbrücken Voice Database, https://stimmdb.coli.uni-saarland.de/) with SQLAlchemy (sqlalchemy.org).

Features
--------

* Auto-download the database file at https://stimmdb.coli.uni-saarland.de
* Auto-download the associated datasets from Zonedo: https://zenodo.org/records/16874898
* Supports incremental, on-demand download per-pathology
* Stores database information as a local SQLite3 file
* Database and datasets are accessed via SQLAlchemy ORM (Object Relational Mapper)
  classes for ease of use
* Acoustic and EGG signals can be retrieved as NumPy arrays directly
* Supports filters to specify study conditions on pathologies, speaker's gender and age, 
  recording types, etc.
* Fixes known errors in the dataset (i.e., corrupted files and swapping of acoustic/EGG data)

Install
-------

.. code-block:: bash

  pip install sbvoicedb

If you prefer manually downloading the full dataset from Zonedo (`data.zip`, the 
full dataset, 17.9 GB) you may download the file first and unzip the content 
to a directory. Make sure that the zip file's internal structure is preserved.
If you're placing your downloaded database in ``my_svd`` folder, its directory
structure should appear like this:

.. code-block::

  .../my_svd/
  └── data/
      ├── 1/
      │   ├── sentnces
      │   │   ├── 1-phrase.nsp
      │   │   └── 1-phrase-egg.egg
      │   └── vowels
      │       ├── 1-a_h.nsp
      │       ├── 1-a_h.nsp
      │       ⋮
      │       └── 1-u_n-egg.egg
      ├── 2/
      │   │   ├── 2-phrase.nsp
      │   │   └── 2-phrase-egg.egg
      │   └── vowels
      │       ├── 2-a_h.nsp
      │       ├── 2-a_h.nsp
      │       ⋮
      │       └── 2-u_n-egg.egg
      ⋮

Examples
--------

.. code-block:: python

  from sbvoicedb import SbVoiceDb

  dbpath = '<path to the root directory of the extracted database>'

  # to create a database instance 
  db = SbVoiceDb(dbpath)
  # - if no downloaded database data found, it'll automatically download the database (not files)

This creates a new database instance. If ``dbpath`` does not contain the SQLite
database file, ``sbvoice.db``, it gets populated from the downloaded CSV file.

.. note::

  The ``sbvoice.db`` database file can be viewed using any SQLite database viewer
  such as DB Browser for SQLite (https://sqlitebrowser.org/)

If any portion of the dataset is already available in ``data`` subdirectory, it 
further populates the recordings table. These database population processes are
visualized with progress bars in the console.

By default, no dataset will be downloaded at this point. You can check how much
of the datasets are available by

.. code-block:: python

  print(f"{db.number_of_sessions_downloaded}/{db.number_of_all_sessions}")

The ``db.number_of_all_sessions`` property should always return 2043.

There are 4 tables to the SQLite database: ``pathologies``, ``speakers``, 
``recording_sessions``, and ``recordings``. The contents of these tables can be 
accessed by 

.. code-block:: python

  db.get_pathology_count()
  db.get_speaker_count()
  db.get_session_count()
  db.get_recording_count()

  db.iter_pathologies()
  db.iter_speakers()
  db.iter_sessions()
  db.iter_recordings()

Your study may not require all the recordings. In such case, you can set filters
on each table when creating the database object. For example, the following creates
a subset of the database which only consists of recordings of sustained /a/ or /i/
at normal pitch, uttered by women of age between 50 and 70 with normal voice or 
with a diagnosis of Laryngitis:

.. code-block:: python

  from sbvoicedb import Pathology, Speaker, RecordingSession, Recording, sql_expr

  db_laryngitis = database.SbVoiceDb(
      dbdir,
      pathology_filter=Pathology.name == "Laryngitis",
      include_healthy=True,
      speaker_filter=Speaker.gender == "w",
      session_filter=RecordingSession.speaker_age.between(50, 70),
      recording_filter=Recording.utterance.in_(("a_n", "i_n")),
  )
  print(f"number of pathologies found: {db_laryngitis.get_pathology_count()}")
  print(f"number of recording sessions found: {db_laryngitis.get_session_count()}")
  print(f"number of unique speakers: {db_laryngitis.get_speaker_count()}")
  print(f"number of recordings: {db_laryngitis.get_recording_count()}")

.. code-block::

  number of pathologies found: 1
  number of recording sessions found: 45
  number of unique speakers: 44
  number of recordings: 90

You can iterate over the rows of any of the tables:

.. code-block:: python

  # iterate over included pathologies
  for patho in db_laryngitis.iter_pathologies():
    print(f'{patho.id)}: {patho.name} ({patho.downloaded})'

  # iterate over included speakers
  for speaker in db_laryngitis.iter_speakers():
    print(f'{speaker.id)}: {speaker.gender}'

  # iterate over included recording sessions
  for session in db_laryngitis.iter_sessions():
    print(f'{session.id)}: speaker_id={session.speaker_id}, speaker_age={session.speaker_age}, speaker_health={session.type}'

  # iterate over included recordings
  for rec in db_laryngitis.iter_recordings():
    print(f'{rec.id)}: session_id={rec.session_id}, utterance={rec.utterance}, nspfile={rec.nspfile}, eggfile={rec.eggfile}'

To retrieve the acoustic and egg data, use ``Recording.nspdata`` and ``Recording.eggdata``:

.. code-block:: python

  import numpy as np
  from matplotlib import pyplot as plt

  rec = next(db_laryngitis.iter_recordings())

  t = np.arange(rec.length)/rec.rate

  fig, axes = plt.subplots(2, 1, sharex=True)
  axes[0].plot(t,rec.nspdata)
  axes[0].set_ylabel('acoustic data')
  axes[1].plot(t,rec.eggdata)
  axes[1].set_ylabel('EGG data')
  axes[1].set_xlabel('time (s)')
  plt.tight_layout()
  plt.show()

.. Data Modifications
.. ------------------

.. SVD Dataset has several 

.. 713-i_n/-iau - corrupted NSP/EGG files

.. 980-iau.wav/980-iau-egg.wav - acoustic and EGG waveforms were flipflopped at n = 583414

.. 980-phrase.wav/980-phrase-egg.wav - acoustic & Egg files were named backwards

.. 1697-iau.wav/1697-iau-egg.wav - acoustic & Egg files were named backwards
.. 1697-phrase.wav/1697-phrase-egg.wav - acoustic & Egg files were named backwards

.. 139-xxx, 141-xxx - acoustic & egg swapped

.. Downloaded vowel files
.. 1573 normal vowels (i-a-u) not cut correctly, recreated

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "sbvoicedb",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "multimedia",
    "author": null,
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/1c/f1/a4e83023b865689b63711cf5a3e7c65e4deff8f89f017145f3337c7bd08d/sbvoicedb-0.3.0.tar.gz",
    "platform": null,
    "description": "`sbvoicedb`: Saarbrueken Voice Database Reader module\n======================================================\n\n|pypi| |status| |pyver| |license|\n\n.. |pypi| image:: https://img.shields.io/pypi/v/sbvoicedb\n  :alt: PyPI\n.. |status| image:: https://img.shields.io/pypi/status/sbvoicedb\n  :alt: PyPI - Status\n.. |pyver| image:: https://img.shields.io/pypi/pyversions/sbvoicedb\n  :alt: PyPI - Python Version\n.. |license| image:: https://img.shields.io/github/license/tikuma-lsuhsc/python-sbvoicedb\n  :alt: GitHub\n\n\nThis Python module provides capability to download and organize Saarbr\u00fccker Stimmdatenbank \n(Saarbr\u00fccken Voice Database, https://stimmdb.coli.uni-saarland.de/) with SQLAlchemy (sqlalchemy.org).\n\nFeatures\n--------\n\n* Auto-download the database file at https://stimmdb.coli.uni-saarland.de\n* Auto-download the associated datasets from Zonedo: https://zenodo.org/records/16874898\n* Supports incremental, on-demand download per-pathology\n* Stores database information as a local SQLite3 file\n* Database and datasets are accessed via SQLAlchemy ORM (Object Relational Mapper)\n  classes for ease of use\n* Acoustic and EGG signals can be retrieved as NumPy arrays directly\n* Supports filters to specify study conditions on pathologies, speaker's gender and age, \n  recording types, etc.\n* Fixes known errors in the dataset (i.e., corrupted files and swapping of acoustic/EGG data)\n\nInstall\n-------\n\n.. code-block:: bash\n\n  pip install sbvoicedb\n\nIf you prefer manually downloading the full dataset from Zonedo (`data.zip`, the \nfull dataset, 17.9 GB) you may download the file first and unzip the content \nto a directory. Make sure that the zip file's internal structure is preserved.\nIf you're placing your downloaded database in ``my_svd`` folder, its directory\nstructure should appear like this:\n\n.. code-block::\n\n  .../my_svd/\n  \u2514\u2500\u2500 data/\n      \u251c\u2500\u2500 1/\n      \u2502   \u251c\u2500\u2500 sentnces\n      \u2502   \u2502   \u251c\u2500\u2500 1-phrase.nsp\n      \u2502   \u2502   \u2514\u2500\u2500 1-phrase-egg.egg\n      \u2502   \u2514\u2500\u2500 vowels\n      \u2502       \u251c\u2500\u2500 1-a_h.nsp\n      \u2502       \u251c\u2500\u2500 1-a_h.nsp\n      \u2502       \u22ee\n      \u2502       \u2514\u2500\u2500 1-u_n-egg.egg\n      \u251c\u2500\u2500 2/\n      \u2502   \u2502   \u251c\u2500\u2500 2-phrase.nsp\n      \u2502   \u2502   \u2514\u2500\u2500 2-phrase-egg.egg\n      \u2502   \u2514\u2500\u2500 vowels\n      \u2502       \u251c\u2500\u2500 2-a_h.nsp\n      \u2502       \u251c\u2500\u2500 2-a_h.nsp\n      \u2502       \u22ee\n      \u2502       \u2514\u2500\u2500 2-u_n-egg.egg\n      \u22ee\n\nExamples\n--------\n\n.. code-block:: python\n\n  from sbvoicedb import SbVoiceDb\n\n  dbpath = '<path to the root directory of the extracted database>'\n\n  # to create a database instance \n  db = SbVoiceDb(dbpath)\n  # - if no downloaded database data found, it'll automatically download the database (not files)\n\nThis creates a new database instance. If ``dbpath`` does not contain the SQLite\ndatabase file, ``sbvoice.db``, it gets populated from the downloaded CSV file.\n\n.. note::\n\n  The ``sbvoice.db`` database file can be viewed using any SQLite database viewer\n  such as DB Browser for SQLite (https://sqlitebrowser.org/)\n\nIf any portion of the dataset is already available in ``data`` subdirectory, it \nfurther populates the recordings table. These database population processes are\nvisualized with progress bars in the console.\n\nBy default, no dataset will be downloaded at this point. You can check how much\nof the datasets are available by\n\n.. code-block:: python\n\n  print(f\"{db.number_of_sessions_downloaded}/{db.number_of_all_sessions}\")\n\nThe ``db.number_of_all_sessions`` property should always return 2043.\n\nThere are 4 tables to the SQLite database: ``pathologies``, ``speakers``, \n``recording_sessions``, and ``recordings``. The contents of these tables can be \naccessed by \n\n.. code-block:: python\n\n  db.get_pathology_count()\n  db.get_speaker_count()\n  db.get_session_count()\n  db.get_recording_count()\n\n  db.iter_pathologies()\n  db.iter_speakers()\n  db.iter_sessions()\n  db.iter_recordings()\n\nYour study may not require all the recordings. In such case, you can set filters\non each table when creating the database object. For example, the following creates\na subset of the database which only consists of recordings of sustained /a/ or /i/\nat normal pitch, uttered by women of age between 50 and 70 with normal voice or \nwith a diagnosis of Laryngitis:\n\n.. code-block:: python\n\n  from sbvoicedb import Pathology, Speaker, RecordingSession, Recording, sql_expr\n\n  db_laryngitis = database.SbVoiceDb(\n      dbdir,\n      pathology_filter=Pathology.name == \"Laryngitis\",\n      include_healthy=True,\n      speaker_filter=Speaker.gender == \"w\",\n      session_filter=RecordingSession.speaker_age.between(50, 70),\n      recording_filter=Recording.utterance.in_((\"a_n\", \"i_n\")),\n  )\n  print(f\"number of pathologies found: {db_laryngitis.get_pathology_count()}\")\n  print(f\"number of recording sessions found: {db_laryngitis.get_session_count()}\")\n  print(f\"number of unique speakers: {db_laryngitis.get_speaker_count()}\")\n  print(f\"number of recordings: {db_laryngitis.get_recording_count()}\")\n\n.. code-block::\n\n  number of pathologies found: 1\n  number of recording sessions found: 45\n  number of unique speakers: 44\n  number of recordings: 90\n\nYou can iterate over the rows of any of the tables:\n\n.. code-block:: python\n\n  # iterate over included pathologies\n  for patho in db_laryngitis.iter_pathologies():\n    print(f'{patho.id)}: {patho.name} ({patho.downloaded})'\n\n  # iterate over included speakers\n  for speaker in db_laryngitis.iter_speakers():\n    print(f'{speaker.id)}: {speaker.gender}'\n\n  # iterate over included recording sessions\n  for session in db_laryngitis.iter_sessions():\n    print(f'{session.id)}: speaker_id={session.speaker_id}, speaker_age={session.speaker_age}, speaker_health={session.type}'\n\n  # iterate over included recordings\n  for rec in db_laryngitis.iter_recordings():\n    print(f'{rec.id)}: session_id={rec.session_id}, utterance={rec.utterance}, nspfile={rec.nspfile}, eggfile={rec.eggfile}'\n\nTo retrieve the acoustic and egg data, use ``Recording.nspdata`` and ``Recording.eggdata``:\n\n.. code-block:: python\n\n  import numpy as np\n  from matplotlib import pyplot as plt\n\n  rec = next(db_laryngitis.iter_recordings())\n\n  t = np.arange(rec.length)/rec.rate\n\n  fig, axes = plt.subplots(2, 1, sharex=True)\n  axes[0].plot(t,rec.nspdata)\n  axes[0].set_ylabel('acoustic data')\n  axes[1].plot(t,rec.eggdata)\n  axes[1].set_ylabel('EGG data')\n  axes[1].set_xlabel('time (s)')\n  plt.tight_layout()\n  plt.show()\n\n.. Data Modifications\n.. ------------------\n\n.. SVD Dataset has several \n\n.. 713-i_n/-iau - corrupted NSP/EGG files\n\n.. 980-iau.wav/980-iau-egg.wav - acoustic and EGG waveforms were flipflopped at n = 583414\n\n.. 980-phrase.wav/980-phrase-egg.wav - acoustic & Egg files were named backwards\n\n.. 1697-iau.wav/1697-iau-egg.wav - acoustic & Egg files were named backwards\n.. 1697-phrase.wav/1697-phrase-egg.wav - acoustic & Egg files were named backwards\n\n.. 139-xxx, 141-xxx - acoustic & egg swapped\n\n.. Downloaded vowel files\n.. 1573 normal vowels (i-a-u) not cut correctly, recreated\n",
    "bugtrack_url": null,
    "license": "GPL-2.0 License",
    "summary": "Saarbrueken Voice Database Downloader and Reader",
    "version": "0.3.0",
    "project_urls": {
        "Issues": "https://github.com/tikuma-lsuhsc/python-sbvoicedb/issues",
        "Pull_Requests": "https://github.com/tikuma-lsuhsc/python-sbvoicedb/pulls",
        "Repository": "https://github.com/tikuma-lsuhsc/python-sbvoicedb"
    },
    "split_keywords": [
        "multimedia"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e2fddc35a3638b87d010059e399bf5e04a307445f97f8330b4ea11cece274a3a",
                "md5": "91769e251e3f3e9bfc42ee4a3e78a85b",
                "sha256": "8d14068e3f6ba981a8408b3997df50e6b7ce4384b47f38e7eba19316f0401c50"
            },
            "downloads": -1,
            "filename": "sbvoicedb-0.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "91769e251e3f3e9bfc42ee4a3e78a85b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 25206,
            "upload_time": "2025-09-13T02:13:03",
            "upload_time_iso_8601": "2025-09-13T02:13:03.538607Z",
            "url": "https://files.pythonhosted.org/packages/e2/fd/dc35a3638b87d010059e399bf5e04a307445f97f8330b4ea11cece274a3a/sbvoicedb-0.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1cf1a4e83023b865689b63711cf5a3e7c65e4deff8f89f017145f3337c7bd08d",
                "md5": "813f8ab8c3a8f372b897228bace76fe6",
                "sha256": "428b963cf3f6d5dc79b1463acfb573c1f0d08b8b964a5a2f98640a4f401f3413"
            },
            "downloads": -1,
            "filename": "sbvoicedb-0.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "813f8ab8c3a8f372b897228bace76fe6",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 27435,
            "upload_time": "2025-09-13T02:13:05",
            "upload_time_iso_8601": "2025-09-13T02:13:05.317572Z",
            "url": "https://files.pythonhosted.org/packages/1c/f1/a4e83023b865689b63711cf5a3e7c65e4deff8f89f017145f3337c7bd08d/sbvoicedb-0.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-13 02:13:05",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "tikuma-lsuhsc",
    "github_project": "python-sbvoicedb",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "sbvoicedb"
}
        
Elapsed time: 9.34911s