Skip to content

Wandas 0.11.0

Wandas 0.11.0 makes Recipes easier to run and to scale. A Recipe can name intermediate steps and return the one you choose, run over many recordings with apply_files, and accept a Frame directly. Audio can be read and kept in float32 to halve memory, welch() no longer needs ten times the input in memory, and describe() and plot() show their figures in plain scripts and PyScript pages.

Wandas 0.11.0では、Recipeを動かしやすく、大きなデータにも使いやすくしました。途中の段に名前を付けて 選んだ段を返す、apply_filesで多数の録音に掛ける、Frameをそのまま渡す、ができるようになりました。 音声をfloat32で読み込んで処理してメモリを半分にでき、welch()は入力の10倍ものメモリを使わなくなり、 describe()とplot()は素のスクリプトやPyScriptのページでも図を表示します。

Highlights / 主な変更

  • RecipePlan.from_frame(frame, steps={...}) names intermediate Frames, and plan.apply(x, step=name) returns the chosen one (Recipe schema 4). 途中のFrameに名前を付けてPlanに入れ、plan.apply(x, step=名前)でその段を返せます(Recipe schema 4)。
  • RecipePlan.apply_files(paths, out_dir) applies a Recipe to many recordings, in parallel with jobs, and returns a table of results. RecipePlan.apply_files(paths, out_dir)でRecipeを多数の録音に掛けられます。jobsで並列に実行し、 結果を表で返します。
  • plan.apply(frame) works for a one-input plan, and RecipeExecutionError names the failing node. 入力が1つのPlanはplan.apply(frame)で実行でき、RecipeExecutionErrorは失敗したノードを示します。
  • wandas.read(..., dtype="float32") and wandas.set_default_dtype("float32") read and generate float32 data; filters, FFT/STFT, N-octave and time-varying psychoacoustic operations keep float32 input in float32. wandas.read(..., dtype="float32")とwandas.set_default_dtype("float32")でfloat32のデータを 読み込み・生成できます。フィルタ・FFT/STFT・N-octave・時間変化する心理音響の操作はfloat32の入力をfloat32のまま返します。
  • welch() with average="mean" uses about a third of the memory on long recordings. welch()(average="mean")は、長い録音で使うメモリが約3分の1になりました。
  • RecipeRegistry.describe() reports each operation's receiver, result type and extras. RecipeRegistry.describe()が、操作ごとに呼べるFrameの型・結果の型・必要なextraを返します。
  • describe() shows figures outside notebooks, and describe()/plot() display on PyScript pages. describe()はノートブックの外でも図を表示し、describe()とplot()はPyScriptのページに図を出します。

Changes / 変更一覧

Documentation: the README rewrite (#553), the browser live demo (#555, #557) and the logo removal (#561). ドキュメント:READMEの書き直し(#553)、ブラウザで動くライブデモ(#555、#557)、ロゴの削除(#561)。

Compatibility and migration / 互換性と移行

Recipes with steps (schema 4) saved by 0.11.0 do not load in 0.10.0 or earlier; plans without steps are still saved as schema 3. Operations such as filters, FFT/STFT, N-octave and time-varying psychoacoustic metrics now return float32 for float32 input (float64 and integer input are unchanged; steady-state loudness_zwst and sharpness_din_st values stay float64).

0.11.0で段(steps)を持つPlanを保存したRecipe(schema 4)は0.10.0以前では読み込めません。 段のないPlanはこれまでどおりschema 3で保存されます。float32の入力は、フィルタ・FFT/STFT・ N-octave・時間変化する心理音響指標などの操作でfloat32のまま返るようになりました(float64・整数の入力は変わりません。 loudness_zwst・sharpness_din_stの定常値は引き続きfloat64です)。

Affected surface or artifact Classification Deprecation start Replacement or migration Removal/change version Exception reason and decision link
Recipe JSON of a RecipePlan with named steps Serialized, new schema 4 Not applicable Plans without steps are still saved as schema 3; upgrade readers to 0.11.0 before exchanging Recipes with steps 0.11.0 Maintainer accepts breaking Recipe format changes; #564, #578
Filter, a_weighting, rms_trend, fade, FFT/STFT and inverse, N-octave, cepstral and psychoacoustic Recipe nodes on float32 input Serialized, semantic change without a version bump None Replays on float32 input return float32 (complex64), differing from earlier float64 results at single-precision rounding; cast the input with astype("float64") to get the earlier values 0.11.0 float64 and integer input are unchanged; maintainer decision that operations follow the input dtype; #563
ChannelFrame.describe() with default arguments outside a notebook Stable, semantic change None Figures are shown with one matplotlib.pyplot.show() and closed; pass is_close=False to get the figures without showing them 0.11.0 It previously raised ImportError without IPython or printed object text; #551
RecipeExecutionError raised inside an operation during RecipePlan.apply Stable, semantic change None It is now wrapped in a new RecipeExecutionError for the node being applied; read cause (or __cause__) for the inner error 0.11.0 So node_id and operation name the node of the plan being applied; #571
welch(average="mean") values, including wandas.audio.welch version 3 Recipe replays Stable / Serialized, numeric change at rounding level without a version bump None None needed; results match the earlier single call within the input precision's rounding (about 1e-15 relative for float64, 1e-6 for float32) 0.11.0 Bounded memory on long recordings; the operation version stays because only rounding changes; #573
影響する機能・データ 分類 非推奨の開始 代替・移行方法 変更バージョン 例外の理由と判断のリンク
名前付きの段を持つRecipePlanのRecipe JSON Serialized、新しいschema 4 該当なし 段のないPlanは引き続きschema 3で保存されます。段を持つRecipeをやり取りする前に、読む側を0.11.0に揃えてください 0.11.0 Recipe形式の互換性のない変更はメンテナーが許容。#564、#578
float32入力に対するフィルタ・a_weighting・rms_trend・fade・FFT/STFTと逆変換・N-octave・ケプストラム・心理音響のRecipeノード Serialized、versionを上げない意味の変更 なし float32入力の再生結果はfloat32(complex64)になり、以前のfloat64の結果と単精度の丸め分だけ異なります。以前の値が必要なら入力をastype("float64")にしてください 0.11.0 float64と整数の入力は変わりません。操作は入力のdtypeに従うというメンテナーの判断。#563
ノートブックの外で既定の引数のまま呼んだChannelFrame.describe() Stable、意味の変更 なし 図をmatplotlib.pyplot.show()で1回表示して閉じます。表示せずに図を受け取るにはis_close=Falseを渡してください 0.11.0 以前はIPythonが無いとImportErrorになるか、オブジェクトの文字列が出るだけでした。#551
RecipePlan.apply中に操作の中で送出されたRecipeExecutionError Stable、意味の変更 なし 実行中のノードのRecipeExecutionErrorで包むようになりました。元のエラーはcause(または__cause__)で取得できます 0.11.0 node_idとoperationが実行中のPlanのノードを指すようにするため。#571
welch(average="mean")の値(wandas.audio.welch version 3のRecipe再生を含む) Stable / Serialized、versionを上げない丸め程度の数値の変更 なし 対応は不要です。以前の1回の呼び出しと、入力の精度の丸め誤差(float64で相対1e-15程度、float32で1e-6程度)の範囲で一致します 0.11.0 長い録音のメモリを抑えるため。丸めだけの変化なので操作versionは上げていません。#573

Added / 追加

  • RecipeExecutionError now has node_id, operation and cause attributes. When an operation fails during RecipePlan.apply, they name the failing node, its registered operation id and the original exception (the same object as __cause__), so a tool can mark the failed step without parsing the message. Errors not tied to one node, such as mismatched input names, have None there. A RecipeExecutionError raised inside an operation (for example by a nested apply) is now wrapped like any other failure, so these attributes name the node of the plan being applied; its message appears after Cause:. When the error is pickled, cause is left out like __cause__. Other message texts are unchanged. RecipeExecutionErrorにnode_id・operation・cause属性を追加しました。 RecipePlan.applyで処理が失敗すると、失敗したノード、その登録済み操作ID、元の例外 (__cause__と同じ)が入るので、エラー文を読まずに失敗した手順に印を付けられます。 入力名の不一致のようにノードに関係しないエラーではNoneです。操作の中で送出された RecipeExecutionError(入れ子のapplyなど)も他の失敗と同じく包むようになり、属性は実行中の Planのノードを指します(元のエラー文はCause:の後に入ります)。pickleではcauseを __cause__と同じく含めません。それ以外のエラー文は変わりません。
  • RecipePlan.apply accepts the Frame (or array) itself when the plan has one input: plan.apply(frame) is the same as plan.apply({plan.inputs[0].name: frame}). A plan with several inputs still needs the mapping; one value raises RecipeExecutionError with the input names. Passing a mapping works as before. 入力が1つのRecipePlanは、plan.apply(frame)のようにFrame(または配列)をそのまま 渡せるようになりました。plan.apply({plan.inputs[0].name: frame})と同じです。入力が 複数のPlanに値を1つだけ渡すと、入力名を示したRecipeExecutionErrorになります。 辞書での渡し方はこれまでどおり使えます。
  • RecipeRegistry.describe() / RecipeOperation.describe() now report, for each operation, the Frame classes it is called on (receiver), the Frame class it returns (returns, or "receiver" when the result keeps the caller's type), and the optional extras it needs (extras, for example ("psychoacoustic",) for noct_synthesis). recipe_operation and RecipeOperation take a new extras argument for extension operations. RecipeOperationDescription.applies_to(frame) tells whether a Frame accepts the operation, including subclasses that override the method. Existing fields and positional construction are unchanged. RecipeRegistry.describe()/RecipeOperation.describe()が、操作ごとに呼べるFrameの型 (receiver)、結果のFrameの型(returns。呼んだFrameと同じ型なら"receiver")、 必要なextra(extras。例:noct_synthesisは("psychoacoustic",))を返すようになりました。 拡張の操作向けに、recipe_operationとRecipeOperationにextras引数を追加しました。 RecipeOperationDescription.applies_to(frame)で、メソッドを上書きしたサブクラスも含めて そのFrameに操作を呼べるかを判定できます。 既存の項目と位置引数での生成は変わりません。
  • RecipePlan.apply_files(paths, out_dir, *, root=None, jobs=1, on_error="continue", overwrite=False) applies a one-input plan to many recordings: it reads each with wandas.read, applies the plan, and saves the result as WDF under out_dir (a.wav becomes a.wav.wdf; with root, the folders below it are kept). A failed recording is recorded and the rest go on, unless on_error="raise". jobs runs recordings in separate processes. It returns a pandas table with path, status, output, error and seconds per recording. 入力が1つのRecipePlanを多数の録音に掛けるRecipePlan.apply_filesを追加しました。録音ごとに wandas.readで読み、Planを実行し、結果をout_dirにWDFで保存します(a.wavはa.wav.wdf。 rootを渡すとその下のフォルダ構成を保ちます)。失敗した録音は記録して先に進みます (on_error="raise"で最初の失敗で止まります)。jobsで別プロセスに分けて並列に実行します。 戻り値は録音ごとのpath・status・output・error・secondsを持つpandasの表です。
  • wandas.read(..., dtype="float32") and ChannelFrame.from_file(..., dtype=...) decode audio directly as float32, halving the memory of the read data. wandas.set_default_dtype("float32"), or with wandas.default_dtype("float32"): for one block, changes the dtype used when dtype is not given, including generate_sin; wandas.get_default_dtype() returns it. The default stays float64. The setting is process-wide and is not stored in Recipes or WDF files. from_folder, from_files and from_table take a dtype argument; without it, a dataset keeps the default in effect when it is created, for every item and derived dataset. apply_files reads with the default in effect when it is called, also in its worker processes, so jobs does not change the result. Later operations keep their current output dtypes. wandas.read(..., dtype="float32")とChannelFrame.from_file(..., dtype=...)で、音声を float32のまま読み込めるようになりました。読み込んだデータのメモリは半分になります。 wandas.set_default_dtype("float32")(1つのブロックだけならwith wandas.default_dtype("float32"):) で、dtypeを省略したときのdtypeを変えられます。generate_sinにも効きます。現在の値は wandas.get_default_dtype()で取得できます。既定はfloat64のままです。この設定はプロセス全体の もので、RecipeとWDFには保存されません。from_folder・from_files・from_tableにはdtype引数が あります。省略すると、データセットを作った時点の既定値を、すべての要素と派生したデータセットで 使います。apply_filesは呼んだ時点の既定値でワーカープロセスでも読むので、jobsで結果は 変わりません。読み込み後の処理の出力dtypeは変わりません。
  • RecipePlan.from_frame(frame, steps={name: other_frame, ...}) names other Frames of the workflow, such as shared preprocessing or a second analysis of it. plan.apply(x, step=name) returns that step instead of the output and builds only the operations it needs; plan.step_names lists the names. apply_files(..., step=name) saves that step, and plan.for_step(name) returns a plan with only that step. Operations the steps share with the output are stored once. A plan still returns one Frame per call. A plan with steps is saved as Recipe schema 4, which older Wandas versions reject; a plan without steps is still saved as schema 3. RecipePlan.from_frame(frame, steps={名前: Frame, ...})で、共通の前処理やそれを使う別の解析などを 名前付きの段としてPlanに入れられるようになりました。plan.apply(x, step=名前)は出力の代わりに その段を返し、必要な処理だけを組み立てます。名前はplan.step_namesで確認できます。 apply_files(..., step=名前)はその段を保存し、plan.for_step(名前)はその段だけのPlanを返します。 出力と共通の処理は1回だけ記録されます。Planが1回の呼び出しで返すFrameは引き続き1つです。 段を持つPlanはRecipe schema 4で保存され、以前のWandasでは読めません。段のないPlanは これまでどおりschema 3で保存されます。

Changed / 変更

  • ChannelFrame.describe() with its defaults now shows its figures outside a notebook. Before, a plain script raised ImportError without IPython and, with IPython installed, only printed Figure(...) and Audio object text. Outside a notebook (a plain script or the terminal IPython shell) it now shows the channel figures with one matplotlib.pyplot.show() call and then closes them; in Matplotlib interactive mode the figures stay open. Audio playback outside PyScript (see below) still needs a notebook with IPython (pip install "wandas[marimo]"). Display in Jupyter, VS Code, Colab and marimo notebooks is unchanged. ChannelFrame.describe()を既定の引数のまま呼んだとき、ノートブックの外でも図が表示されるように なりました。これまでは素のスクリプトで、IPythonがなければImportErrorになり、IPythonがあっても Figure(...)とAudioオブジェクトの文字列が出るだけでした。ノートブックの外(素のスクリプトや ターミナルのIPython)では、各チャンネルの図をmatplotlib.pyplot.show()で1回表示してから閉じます。 Matplotlibの対話モードでは図を開いたままにします。PyScript(下記)以外での音声再生には引き続き、IPythonのある ノートブック(pip install "wandas[marimo]")が必要です。Jupyter、VS Code、Colab、marimoの ノートブックでの表示は変わりません。
  • In a PyScript page, ChannelFrame.describe() and the plot() methods now put their figures on the page with pyscript.display() when the running code has an output element (pyscript.current_target()). describe() also adds an HTML audio player for each channel. Before, the figures went to matplotlib.pyplot.show() and never reached the page. A plot() call that creates its own figure displays and closes it, including overlay=True, so later changes to the returned Axes do not reach the page. plot("describe") is the building block of describe() and is not displayed on its own. py-editor cells have no output target, so they keep the previous behaviour. PyScriptのページでは、実行中のコードに出力先の要素(pyscript.current_target())があるとき、 ChannelFrame.describe()と各plot()がpyscript.display()で図をページに出すようになりました。 describe()はチャンネルごとの音声プレーヤーも出します。これまでは図がmatplotlib.pyplot.show()に 渡されるだけで、ページには表示されませんでした。図を自分で作ったplot()(overlay=Trueも含む)は、 図を表示してから閉じます。そのため、戻り値のAxesをその後に変更してもページには反映されません。 plot("describe")はdescribe()の部品なので、単独では表示しません。 py-editorのセルには出力先がないので、これまでどおりの動作になります。
  • Saving or loading WDF with h5netcdf installed but without its h5py backend now raises ImportError with pip install "wandas[io]", like a missing h5netcdf already did. Before, the save or load failed with h5netcdf's own message, which did not name the extra. The save and load docstrings and the Recipe How-to now say that WDF needs the io extra. h5netcdfは入っていてもh5pyが無い環境でWDFを保存・読み込みすると、h5netcdfが無い場合と 同じくpip install "wandas[io]"を示すImportErrorになりました。これまではh5netcdf自身の メッセージになり、extraの名前が出ませんでした。save/loadのdocstringとRecipe How-toにも、 WDFにはio extraが必要なことを書きました。

  • ChannelFrame.welch() with average="mean" (the default) no longer needs about ten times the input in memory for a long recording. It now calls scipy.signal.welch on runs of whole segments and weights each run's mean by its segment count; the segments are the same, so the values match the single call up to rounding in the input's precision (about 1e-15 relative for float64 input, 1e-6 for float32). For 48 kHz, 2 channels, 10 minutes, the peak resident memory during welch(n_fft=2048) went from about 5.0 GB to 1.5 GB. average="median" still uses one call over all segments. ChannelFrame.welch()をaverage="mean"(既定)で使うとき、長い録音で入力の約10倍の メモリを使わなくなりました。セグメント単位の区間ごとにscipy.signal.welchを呼び、 セグメント数で重み付けして平均します。セグメントは同じなので、値は1回の呼び出しと 入力の精度の丸め誤差の範囲で一致します(float64入力で相対1e-15程度、float32で1e-6程度)。48 kHz・2 ch・10分のwelch(n_fft=2048)では、 最大常駐メモリが約5.0 GBから1.5 GBになりました。average="median"はこれまでどおり 全セグメントで1回だけ呼びます。

  • Operations that computed in float64 now keep float32 input in float32 (complex64 for complex results): high_pass_filter, low_pass_filter, band_pass_filter, a_weighting, rms_trend (including dB=True), fade, fft, ifft, stft, istft, noct_spectrum, noct_synthesis, cepstrum, the spectral envelope, loudness_zwtv, sharpness_din, roughness_dw and roughness_dw_spec. They still compute in float64 and round the result, so values differ from float64 input only at single-precision rounding (about 1e-6 relative). dB and dBA of single-precision spectra are float32 too. The psychoacoustic operations already reported float32 before compute but returned float64; the computed data now matches. The steady-state values of loudness_zwst and sharpness_din_st are still float64 NumPy arrays. float64 and integer input are unchanged. Recipe operation versions are not changed, because float64 recordings give the same results as before. float64で計算していた操作が、float32の入力をfloat32のまま(複素数の結果はcomplex64)返す ようになりました。対象はhigh_pass_filter・low_pass_filter・band_pass_filter・ a_weighting・rms_trend(dB=Trueを含む)・fade・fft・ifft・stft・istft・ noct_spectrum・noct_synthesis・cepstrum・スペクトル包絡・loudness_zwtv・sharpness_din・roughness_dw・roughness_dw_specです。 計算は引き続きfloat64で行い、結果を丸めるので、float64入力との差は単精度の丸め (相対1e-6程度)だけです。単精度のスペクトルのdB・dBAもfloat32になります。 心理音響の操作は、compute前はfloat32と示しながらfloat64を返していましたが、計算結果も 一致するようになりました。loudness_zwst・sharpness_din_stの定常値は引き続きfloat64の NumPy配列です。float64と整数の入力は変わりません。 float64の録音では結果が変わらないので、Recipeの操作バージョンは上げていません。

See Wandas 0.10.0 for the previous release.