{"id":16683620,"url":"https://github.com/yamachu/world4py","last_synced_at":"2025-04-09T23:24:41.488Z","repository":{"id":62589471,"uuid":"95285825","full_name":"yamachu/WORLD4py","owner":"yamachu","description":"WORLD python wrapper","archived":false,"fork":false,"pushed_at":"2019-06-04T16:15:34.000Z","size":48,"stargazers_count":9,"open_issues_count":4,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T01:13:38.943Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yamachu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-24T08:37:45.000Z","updated_at":"2022-09-21T15:22:14.000Z","dependencies_parsed_at":"2022-11-03T17:52:33.731Z","dependency_job_id":null,"html_url":"https://github.com/yamachu/WORLD4py","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yamachu%2FWORLD4py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yamachu%2FWORLD4py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yamachu%2FWORLD4py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yamachu%2FWORLD4py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yamachu","download_url":"https://codeload.github.com/yamachu/WORLD4py/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248127277,"owners_count":21052224,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T14:25:34.461Z","updated_at":"2025-04-09T23:24:41.454Z","avatar_url":"https://github.com/yamachu.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WORLD4py\nYet another WORLD Python wrpper library\n\n## WORLD4py とは\n\nM.Morise により開発されている分析合成ライブラリ[WORLD](https://github.com/mmorise/World) の非公式Pythonラッパーライブラリです．\n\nオリジナルの WORLD のインタフェースを一部改変した [WORLD](https://github.com/yamachu/World/tree/type/for_cswrapper) をラップしています．\n変更の差分は[こちら](https://github.com/yamachu/World/compare/master...type/for_cswrapper)で確認することが出来ます．\n\n詳細はオリジナルの WORLD のリポジトリ及び文献を参照してください．\n\n## 特徴\n\n本ライブラリではWORLDでの主要な分析手法である _Dio_, _CheapTrick_, _D4C_ などを抽象化し API として提供しています．\nその他一括して特徴量を抽出する _extract_all_from_waveform_ といったメソッドを提供しています．\n\n本ライブラリは Python の標準モジュールである _ctypes_ を使用した _world4py.native_ と _NumPy_ を使用した _world4py.np_ の2種類が選択可能で _world4py.native_ は環境を制限することなく利用することが可能です．\n\nまた本ライブラリはユーザが独自にビルドした WORLD の Cライブラリ を容易に使うことが出来る薄いラッパーとなっています．\nこれは現在動作確認済みの環境以外のプラットフォーム，および CPUアーキテクチャ においても，その環境にあったライブラリをビルドしこのラッパーに読ませれば利用が可能になるかもしれないということです．\n\n\n## インストール\n\n### 動作確認済みの環境\n\n依存ライブラリが NumPy版のみ NumPy に依存しているだけなので，基本的にはどの環境の Python でも動作すると思います．\n\n実際に確認したプラットフォームは\n* Linux(Ubuntu)\n* macOSX\n* Windows\n\nPython のバージョンは\n* Python 2.7\n* Python 3.5\n\nで確認しています．\n\n\n### インストール方法\n\n今後 pip でのインストールを可能にしますが，現在は _setup.py_ を使用してインストールします．\n\n```\ngit clone https://github.com/yamachu/WORLD4py.git\ncd WORLD4py\npython setup.py install\n```\n\nこのインストール中に使用しているプラットフォームを判別し，あらかじめビルドしてあるネイティブライブラリをダウンロードし展開します．\n\n使用が可能になったかは\n\n```\ncd demo\npython main.py\n```\n\nなどで確認してみてください．\n\n\n## 使い方\n\n### 特徴量抽出および合成\n\nctypes版\n\n```python\nfrom world4py.native import apis, tools\n\n# get waveform from file\nx, fs, nbit = tools.get_wave_parameters('./sample.wav')\n# can use Python wave module\n\n# extract F0\nf0, time_axis = apis.dio(x, fs)\n# extract Spectral envelope\nsp, sp_fft_size = apis.cheap_trick(x, fs, time_axis, f0)\n# extract Aperiodicity\nap, ap_fft_size = apis.d4c(x, fs, time_axis, f0)\n# synthesis\ny, y_length = apis.synthesis(f0, sp, ap, fs, fft_size=sp_fft_size)\n```\n\nこれらの関数により抽出される _f0_, _sp_, _ap_ は ctypes 特有の型になっているため，操作する場合は Python での list のような型に変換する必要があります．\n\nこれを実現するのが以下のコードになります．\n\n```python\nfrom world4py.native import utils\n\n# 1d-Pointer cast to 1d-List\nf0_list = utils.cast_1d_pointer_to_1d_list(f0)\n\n# 2d-Pointer cast to 2d-List\nsp_list = utils.cast_2d_pointer_to_2d_list(sp, len(f0_list), sp_fft_size // 2 + 1)\n\n# do something...\n\n# 2d-List cast to 2d-Pointer\nsp_mod = utils.cast_2d_list_to_2d_pointer(sp_list)\n```\n\n上記のように Python の list型 のような変数を使用する際は，\nutils に定義されるヘルパーメソッドを経由する必要があります．\n\nしかしわざわざ経由させるのは面倒なので，NumPy が使える環境であれば，以下の NumPy 版を使用することを推奨します．\n\nnumpy版\n\n```python\nfrom world4py.np import apis, tools\n\n# get waveform from file\nx, fs, nbit = tools.get_wave_parameters('./sample.wav')\n# can use Python wave module\n\n# extract F0\nf0, time_axis = apis.dio(x, fs)\n# extract Spectral envelope\nsp = apis.cheap_trick(x, fs, time_axis, f0)\n# extract Aperiodicity\nap = apis.d4c(x, fs, time_axis, f0)\n# synthesis\ny  = apis.synthesis(f0, sp, ap, fs)\n```\n\n抽出に関しては基本的には ctypes版 と変わりません．\n戻り値が一部減っていますが，これは ctypes版の戻り値の情報が戻り値の ndarray から取得可能であるために省略しています．\n\n戻り値が ndarray であるため，ctypes版で必要だった utils のヘルパーメソッドがなくても配列をそのまま扱うことが出来ます．\n\n分析時に様々なパラメータを与えることが可能となっています．\n詳細はオリジナルの WORLD や docstring などで確認してください．\n\nこの分析パラメータを一括で設定して，特徴量を上記のように一つずつ求めるのではなく，一括で求めることも出来ます．\n分析パラメータは辞書型で定義するため，JSON形式などへ変換しやすく，分析条件などを管理しやすい形式となっています．\n\n以下のように抽出条件を設定します．\n\n```python\nana_param = {\n    'threshold': 0.3,\n    'frame_period': 5.0,\n    'f0_ceil': 500.0,\n}\n\n# ctypes版での定義\nf0, sp, ap, fft_size, array_size = apis.extract_all_from_waveform(x, fs, param)\n```\n\nパラメータの定義は各分析手法の docstring に記載してあります．\n\n\n### 非公開 API の使用\n\n抽象化されていない WORLD のそのままの API を使用することも可能です．\n\nここでは ctypes を例にとって説明します．\n本ライブラリでは RealtimeSynthesis については API を現在提供していません．\n\nそれを使用する場合は以下のように行います．\n\n```python\n# WORLD の test.cpp の Synthesis2 を参照\nfrom world4py.native import structures, apidefinitions\n\nsynthesizer = structures.WorldSynthesizer()\nbuffer_size = 64\napidefinitions._InitializeSynthesizer(fs, 5.0, sp_fft_size, buffer_size, 1, synthesizer)\nf0_length = len(list(f0))\napidefinitions._AddParameters(f0, f0_length, sp, ap, synthesizer)\nindex = 0\ny_length = int(f0_length * 5.0 * fs // 1000) + 1\ny = (c_double * y_length)()\ni = 0\nwhile apidefinitions._Synthesis2(synthesizer) != 0:\n    index = i * buffer_size\n    for j in range(buffer_size):\n        y[j + index] = synthesizer.buffer[j]\n        \n    i += 1\n    \napidefinitions._DestroySynthesizer(synthesizer)\n```\n\nこのように _apidefinitions_ というモジュール内に各 WORLD の API が先頭にアンダースコアを付与して実装されています．\n\n使いたいけれど抽象化された API が無いという場合はこのような形式で API にアクセスしてください．\n\n\n### 研究用途での使用\n\n研究に使用する場合バージョンの固定などが必要になる場面があると思います．\n本ラッパーはインストール時に [WORLDのリリースページ](https://github.com/yamachu/World/releases) から対象プラットフォームのライブラリをダウンロードしています．\nそのため，Python のラッパーのバージョンが同じでも，内部で使用しているライブラリのバージョンが一致しないといったことが起こることがあります．\n独自拡張のラッパーのバージョンは\n\n```\nimport world4py\n\nworld4py.get_native_library_version()\n```\n\nで取得することが出来ます．\n\nこのバージョンは独自拡張の [WORLDのリリースページ](https://github.com/yamachu/World/releases) のバージョン，\nまたベースとなっているオリジナルの WORLD のコミットハッシュを示しています．\n\n以前のバージョンに戻したい，また自分で少し動作を変えたライブラリを試したいと言った場合は，\n\n```\nimport world4py\n\nworld4py.get_native_library_path()\n```\n\n以上の手順でネイティブライブラリのインストールパスを取得することが出来ます．\nそのパスに存在するライブラリファイルを置き換えることで，バージョンのピンニングなどが行なえます．\n\n今後バージョンを指定し差し替えが可能なインタフェースなども検討しています．\n\n\n#### 他の手段\n\nラッパー側でネイティブライブラリが読み込まれる前に読み込みパスを変更することで対応することも可能です．\nファイルの書き換えなどが必要なく，また User 権限でも可能であるなどのメリットが有ります．\n\n```\nimport world4py\n\nworld4py._WORLD_LIBRARY_PATH = 'HERE IS MY LIBRARY PATH'\n\nfrom world4py.native import apis, tools\n\n# do something\n```\n\nこのように _world4py_ の他のモジュールを呼ぶ以前に _world4py.\\_WORLD\\_LIBRARY\\_PATH_ を書き換えることで読み込み先を変更できます．\n\n---\n\ndemo/sample.wav は [©効果音ラボ](http://soundeffect-lab.info) 様の音声を使用しています．\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyamachu%2Fworld4py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyamachu%2Fworld4py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyamachu%2Fworld4py/lists"}