فهرست مقاله
دو طیف میتوانند مجموعِ توانِ برابر داشته باشند، ولی یکی تقریباً یکنواخت و دیگری پر از قله و فرورفتگی باشد. تختیِ طیفی راهی برای خلاصهکردنِ این تفاوت است؛ البته عددِ بزرگتر، بهتنهایی، صوتِ بهتر را نشان نمیدهد. در این درس از مقادیرِ صحیحِ کوچک و کاملاً ساختگی شروع میکنیم تا معنای نسبت، رفتارِ صفر و اثرِ کفگذاری را جدا ببینیم. هیچ مکالمه، تبدیلِ فوریه، مدلِ گفتار یا کتابخانهٔ تحلیلِ صوت اجرا نمیشود.
۱. تختیِ کدام طیف را اندازه میگیریم؟

ورودی، مجموعهٔ محدودی از سطلهای توانِ نسبی است؛ ترتیبِ هر سطل در مسیرِ آمادهسازیِ بیرونی معلوم فرض میشود. مقدارهای این آموزش وات یا چگالیِ توانِ کالیبرهشده نیستند. چون صورت و مخرج نسبت واحدِ یکسان دارند، تختی بیبعد است. کد از روی این اعداد، نرخِ نمونهبرداری، فرکانسِ هر سطل یا مدتِ قاب را حدس نمیزند؛ این مشخصات باید هنگام تولیدِ طیف جدا ثبت شوند.
برای مقایسهٔ دو قاب، نوعِ طیف، مجموعهٔ سطلها و سیاستِ پیشپردازش باید یکسان باشد. حذفِ مؤلفهٔ DC، محدودکردنِ باند یا افزودنِ یک سطلِ صفر، دادهٔ همین نسبت را عوض میکند. اینجا همهٔ سطلهای دادهشده وزنِ برابر دارند؛ محاسبهٔ انتگرال با فاصلههای فرکانسیِ نامساوی پیاده نشده است. میانگینِ ویژگیِ چند قاب هم با ویژگیِ میانگینِ طیفها الزاماً برابر نیست و در دامنهٔ این مثال قرار ندارد.
در آزمایش FFT و پنجرهٔ Hann، ساختِ طیفِ دامنه و اثرِ افزودنِ صفر بررسی شده بود. آن خروجی را بدون قراردادِ تازه، ورودیِ توانِ این درس نمینامیم. حتی مربعکردنِ دامنه نیز بهتنهایی همهٔ جزئیاتِ نرمالسازیِ توان یا PSD را تعیین نمیکند. مثالِ حاضر عمداً پس از آن تصمیمها شروع میشود و فقط حسابِ یک توصیفگر را بررسی میکند.
۲. میانگینِ هندسی را با مسیرِ لگاریتمی بسازیم

برای n مقدارِ مثبت، میانگینِ حسابی برابر مجموع تقسیم بر n است. میانگینِ هندسی، ریشهٔ nامِ حاصلضربِ همان مقدارهاست و تختی، نسبتِ هندسی به حسابی تعریف میشود. در مثالِ دو سطلیِ یک و چهار، حاصلضرب چهار و میانگینِ هندسی دو است؛ میانگینِ حسابی پنجدوم میشود. بنابراین پاسخِ دقیق چهارپنجم، یعنی ۰٫۸ است. برابر شدنِ توانِ همهٔ سطلها نسبتِ یک میدهد.
مرجعِ رسمیِ gmean در SciPy، رابطهٔ میانگینِ هندسی با نمایِ میانگینِ لگاریتمها را بیان میکند. مسیرِ اصلیِ ما همین همارزیِ ریاضی را برای مقدارهای مثبت به کار میگیرد، اما SciPy فراخوانی نمیشود. ابتدا همهٔ مقدارها را بر بزرگترینِ آنها تقسیم میکنیم؛ مقیاسِ مشترک از نسبت حذف میشود و لگاریتمها در دامنهٔ محدودتری قرار میگیرند.
میانگینِ حسابی از میانگینِ هندسی کوچکتر نیست؛ بنابراین مقدارِ ریاضیِ تختی در بازهٔ صفر تا یک است. کد، لگاریتمِ نسبت را پیش از گرفتنِ نمایی، حداکثر صفر میگیرد تا گردکردنِ شناور، مرزِ بالای ریاضی را رد نکند. این محافظ، جای اعتبارسنجیِ ورودی یا شاهدِ درستیِ عددی نیست. جمعِ لگاریتمها با fsum انجام میشود و مقایسه با مرجعِ مستقل، تلورانسِ مشخصِ خودش را دارد.
۳. صفرِ واقعی و کفگذاری را دو قرارداد جدا بدانیم

اگر دستکم یک سطل صفر باشد و مجموع مثبت بماند، حاصلضرب صفر و میانگینِ هندسی صفر است؛ پس نسبتِ خام صفر میشود. اما در بردارِ سراسر صفر، میانگینِ حسابی نیز صفر است و نسبت تعریف ندارد. تابع برای این حالت وضعیتِ all_zero_undefined و مقدارِ None میدهد که در JSON به null تبدیل میشود؛ صفر یا یک را بهجای مقدارِ تعریفنشده پنهان نمیکند.
در تابعِ کاملِ spectral_flatness در منبعِ رسمیِ librosa، مقدارِ آستانهگذاریشده از بیشینهٔ amin و S به توانِ power ساخته میشود. این عمل، جایگزینیِ مقدارهای کوچک است؛ افزودنِ epsilon به تکتکِ سطلها نیست. مثالِ همان منبع برای طیفِ توانِ آماده، power را یک میگذارد تا توان دوباره مربع نشود. ما رابط و همهٔ رفتارهای این کتابخانه را بازتولید نمیکنیم.
در کدِ ما کفگذاری تابعی جدا و آشکار است. بردارِ صفر و چهار با کفِ یک به یک و چهار تبدیل میشود و نسبتش چهارپنجم خواهد شد؛ درحالیکه نسبتِ خام صفر بود. بردارِ سراسر صفر نیز پس از کفگذاریِ مثبت، یکنواخت و دارای نسبتِ یک میشود. این نتیجه، ویژگیِ دادهٔ جایگزینشده است؛ از آن نمیتوان وجودِ نویزِ واقعی، خوببودنِ سکوت یا کیفیتِ گفتار را نتیجه گرفت.
ناورداییِ مقیاس هم شرط دارد. اگر همهٔ توانهای خام در ضریبِ مثبتِ مشترک ضرب شوند، نسبت تغییر نمیکند؛ ولی ثابت نگهداشتنِ کفِ مطلق هنگام تغییرِ مقیاس، میتواند این برابری را بشکند. بنابراین در گزارشِ آزمایش باید هم نوع و مقیاسِ توان و هم کفِ انتخابشده مشخص باشد. تغییرِ این سیاست، صرفاً تعمیرِ نمایشِ عدد نیست؛ تعریفِ دادهٔ موردِ سنجش را تغییر میدهد.
۴. کدِ کامل را با کرانِ کسریِ مستقل بسنجیم

فایل spectral_flatness_power.py فقط از کتابخانهٔ استاندارد استفاده میکند و نسخهٔ واقعیِ اجرا را داخلِ خروجی ثبت میکند. قراردادِ آموزشیِ ورودی، دقیقاً tuple با یک تا هشت عضو است؛ هر عضو باید دقیقاً int در بازهٔ صفر تا یکمیلیون باشد. bool، زیرکلاسها، عددِ شناور، رشته و مولد رد میشوند. این سقفها استانداردِ فایلِ صوتی نیستند؛ دامنهٔ محدود و قابلبررسیِ همین مثالاند.
"""Finite supplied-power spectral flatness; no waveform, STFT or library run."""
from fractions import Fraction
from itertools import permutations, product
import json
import math
import platform
import sys
MAX_BINS = 8
MAX_POWER = 1_000_000
ABS_TOLERANCE = 1e-12
def validate_powers(powers):
if type(powers) is not tuple or not 1 <= len(powers) <= MAX_BINS:
raise ValueError("powers must be an exact tuple of length 1..8")
if any(type(value) is not int for value in powers):
raise TypeError("each relative-power bin must be an exact int, not bool")
if any(not 0 <= value <= MAX_POWER for value in powers):
raise ValueError("relative-power bins must be in 0..1000000")
return powers
def spectral_flatness(powers):
values = validate_powers(powers)
total = sum(values)
if total == 0:
return {"status": "all_zero_undefined", "flatness": None,
"bin_count": len(values), "relative_power_sum": total}
if 0 in values:
answer, status = 0.0, "zero_bin"
else:
# Normalize first; every logarithm sees a value in [1e-6, 1].
largest = max(values)
log_geometric = math.fsum(math.log(x / largest) for x in values) / len(values)
arithmetic = total / (len(values) * largest)
log_ratio = log_geometric - math.log(arithmetic)
# AM >= GM: cap positive floating roundoff at its mathematical boundary.
answer, status = math.exp(min(0.0, log_ratio)), "positive"
return {"status": status, "flatness": answer,
"bin_count": len(values), "relative_power_sum": total}
def floor_powers(powers, minimum):
values = validate_powers(powers)
if type(minimum) is not int:
raise TypeError("floor must be an exact int, not bool")
if not 0 <= minimum <= MAX_POWER:
raise ValueError("floor must be in 0..1000000")
# An explicit new data set: replacement by maximum, not addition.
return tuple(max(minimum, x) for x in values)
def integer_product_bracket(values, steps=64):
"""Independent exact oracle for trusted integer fixtures, not validation.
F^n * total^n = n^n * product. Compare rational powers with an exact
integer product; never call the main function, log, exp or float roots.
"""
count = len(values)
total = sum(values)
if total == 0:
return None
multiplied = 1
for value in values:
multiplied *= value
if multiplied == 0:
return Fraction(0), Fraction(0)
average = Fraction(total, count)
lower, upper = Fraction(0), Fraction(1)
for _ in range(steps):
middle = (lower + upper) / 2
if (middle * average) ** count <= multiplied:
lower = middle
else:
upper = middle
return lower, upper
def close(left, right):
return math.isclose(left, right, rel_tol=0.0, abs_tol=ABS_TOLERANCE)
def rejects(error, function, *args):
try:
function(*args)
except error:
return True
return False
def run_example():
checks = {}
hand = spectral_flatness((1, 4))
hand_repeat = spectral_flatness((1, 4, 1, 4))
checks["hand_geometric_two_arithmetic_five_halves_ratio_four_fifths"] = (
hand["status"] == "positive" and close(hand["flatness"], 4 / 5)
and close(hand_repeat["flatness"], 4 / 5))
uniform = [spectral_flatness((value,) * count)
for value in (1, 3, MAX_POWER) for count in (1, 2, MAX_BINS)]
checks["positive_uniform_and_single_bin_are_one"] = all(
row["status"] == "positive" and row["flatness"] == 1.0 for row in uniform)
partial = spectral_flatness((0, 4))
silence = spectral_flatness((0, 0))
checks["partial_zero_is_zero_but_all_zero_is_undefined"] = (
partial["status"] == "zero_bin" and partial["flatness"] == 0.0
and silence == {"status": "all_zero_undefined", "flatness": None,
"bin_count": 2, "relative_power_sum": 0})
family_cases, family_zero, family_undefined = 0, 0, 0
maximum_difference, maximum_bracket_width = 0.0, Fraction(0)
oracle_ok = True
for count in range(1, 6):
for values in product((0, 1, 4), repeat=count):
actual = spectral_flatness(values)
bracket = integer_product_bracket(values)
family_cases += 1
if bracket is None:
family_undefined += 1
oracle_ok = oracle_ok and actual["flatness"] is None
continue
lower, upper = bracket
total, multiplied = sum(values), math.prod(values)
average = Fraction(total, count)
exact_enclosure = ((lower * average) ** count <= multiplied
<= (upper * average) ** count)
midpoint = float((lower + upper) / 2)
maximum_difference = max(maximum_difference,
abs(actual["flatness"] - midpoint))
maximum_bracket_width = max(maximum_bracket_width, upper - lower)
within_tolerance = (float(lower) - ABS_TOLERANCE <= actual["flatness"]
<= float(upper) + ABS_TOLERANCE)
oracle_ok = (oracle_ok and exact_enclosure and within_tolerance
and 0 <= actual["flatness"] <= 1
and upper - lower <= Fraction(1, 2 ** 64))
family_zero += multiplied == 0
checks["exact_integer_power_rational_brackets_finite_family_one_group"] = oracle_ok
seed = (1, 4, 9, 16)
original = spectral_flatness(seed)
permuted = [spectral_flatness(p)["flatness"] for p in permutations(seed)]
checks["bin_permutation_preserves_unweighted_descriptor"] = all(
close(value, original["flatness"]) for value in permuted)
scale_seed = (1, 3, 7)
scale_rows = [spectral_flatness(tuple(scale * x for x in scale_seed))
for scale in (1, 2, 17, 100_000)]
checks["common_positive_scale_preserves_ratio_inside_own_bounds"] = all(
close(row["flatness"], scale_rows[0]["flatness"]) for row in scale_rows)
magnitude = spectral_flatness((1, 2))
power = spectral_flatness((1, 4))
checks["magnitude_and_power_representations_are_not_interchangeable"] = (
close(magnitude["flatness"], 0.9428090415820634)
and close(power["flatness"], 0.8)
and magnitude["flatness"] > power["flatness"] + 0.1)
clipped = floor_powers((0, 1, 4), 1)
replaced = spectral_flatness(floor_powers((0, 4), 1))
checks["floor_is_explicit_maximum_replacement_not_additive_epsilon"] = (
clipped == (1, 1, 4) and clipped != (1, 2, 5)
and floor_powers((1, 4), 0) == (1, 4)
and close(replaced["flatness"], 4 / 5)
and not close(spectral_flatness(floor_powers((0, 8), 1))["flatness"],
replaced["flatness"])
and close(spectral_flatness(floor_powers((0, 8), 2))["flatness"],
replaced["flatness"]))
floored_silence = spectral_flatness(floor_powers((0, 0), 1))
checks["floored_all_zero_becomes_one_without_redefining_raw_silence"] = (
floored_silence["status"] == "positive"
and floored_silence["flatness"] == 1.0
and spectral_flatness((0, 0))["flatness"] is None)
checks["bin_set_changes_metric_but_repeating_whole_pattern_does_not"] = (
spectral_flatness((1, 4, 0))["flatness"] == 0.0
and close(spectral_flatness((1, 4, 1, 4))["flatness"], hand["flatness"])
and spectral_flatness((4,))["flatness"] == 1.0)
boundary = spectral_flatness((1,) + (MAX_POWER,) * 7)
bound_oracle = integer_product_bracket((1,) + (MAX_POWER,) * 7)
low, high = bound_oracle
checks["closed_length_and_integer_power_bounds_are_computable"] = (
boundary["bin_count"] == MAX_BINS
and float(low) - ABS_TOLERANCE <= boundary["flatness"]
<= float(high) + ABS_TOLERANCE
and floor_powers((0,) * 8, MAX_POWER) == (MAX_POWER,) * 8)
class IntSubclass(int):
pass
class TupleSubclass(tuple):
pass
invalid = [(), (0,) * 9, [1, 4], (True,), (1.0,), (Fraction(1),),
("1",), (-1,), (MAX_POWER + 1,), (10 ** 500,),
(float("nan"),), (float("inf"),), (complex(1),),
(IntSubclass(1),), TupleSubclass((1, 4)), None,
(x for x in (1, 4))]
invalid_floors = (True, -1, MAX_POWER + 1, 1.0, Fraction(1), None)
rejected = sum(rejects((TypeError, ValueError), spectral_flatness, x)
for x in invalid)
floor_rejected = sum(rejects((TypeError, ValueError), floor_powers, (0, 4), x)
for x in invalid_floors)
checks["strict_types_containers_values_and_floor_contract_rejected"] = (
rejected == len(invalid) and floor_rejected == len(invalid_floors))
data = (0, 1, 4)
before = data
first = spectral_flatness(data)
second = spectral_flatness(data)
transformed = floor_powers(data, 1)
first["flatness"] = 999
checks["inputs_immutable_and_result_mappings_independent"] = (
data is before and data == (0, 1, 4) and transformed == (1, 1, 4)
and transformed is not data and second["flatness"] == 0.0
and spectral_flatness(data)["flatness"] == 0.0)
rows = (hand, partial, silence, floored_silence, boundary)
checks["all_states_use_strict_JSON_null_not_nonfinite_numbers"] = all(
json.loads(json.dumps(row, allow_nan=False)) == row for row in rows)
assert len(checks) == 14 and all(type(v) is bool and v for v in checks.values()), checks
return {"runtime": {"python": platform.python_version(),
"implementation": platform.python_implementation(),
"dependencies": "standard library only"},
"supplied_data": "synthetic relative power bins, not waveform/STFT output",
"domain": {"exact_container": "tuple", "bin_count": [1, MAX_BINS],
"exact_value_type": "int; bool and subclasses rejected",
"relative_power_range": [0, MAX_POWER]},
"hand_power_bins": [1, 4], "hand_geometric_mean": 2,
"hand_arithmetic_mean": "5/2", "hand_exact_flatness": "4/5",
"hand_result": hand, "partial_zero_result": partial,
"all_zero_result": silence, "floor_one_result": replaced,
"floored_all_zero_result": floored_silence,
"magnitude_counterexample": magnitude,
"largest_domain_example": boundary,
"oracle": {"algorithm": "integer product and rational-power bisection; no logs/exp",
"bisection_steps": 64,
"exact_bracket_width_maximum": str(maximum_bracket_width),
"finite_cases_in_one_group": family_cases,
"partial_zero_cases": family_zero,
"all_zero_undefined_cases": family_undefined,
"max_float_difference_to_bracket_midpoint": maximum_difference,
"comparison_absolute_tolerance": ABS_TOLERANCE,
"float_need_not_lie_inside_exact_rational_bracket": True},
"permutation_cases_in_one_group": len(permuted),
"invalid_power_fixtures_in_one_group": rejected,
"invalid_floor_fixtures_in_same_group": floor_rejected,
"roundoff_boundary_policy": "positive computed log-ratio capped at zero, AM>=GM",
"limitations": "No FFT/STFT, librosa/SciPy, physical power, perceptual quality or classifier run",
"checks": checks, "unique_check_groups": len(checks)}
if __name__ == "__main__":
result = run_example()
sys.stdout.buffer.write((json.dumps(result, ensure_ascii=True, indent=2,
allow_nan=False) + "\n").encode("utf-8"))
مرجعِ مستقل، لگاریتم یا نمایی ندارد. مجموع و حاصلضربِ مقدارهای صحیح را میسازد و نسبتِ مطلوب را میانِ صفر و یک محصور میکند. برای هر نامزدِ کسریِ F، بررسی میکند آیا توانِ nامِ حاصلضربِ F در میانگینِ حسابی، از حاصلضربِ صحیحِ سطلها بیشتر شده است یا نه. این مقایسه با Fraction دقیق انجام میشود؛ پس مسیرِ عددیِ اصلی برای ساختنِ انتظار دوباره صدا زده نشده است.
شصتوچهار نصفکردن، پهنایِ کرانِ کسریِ مثبت را به دو به توانِ منفیِ شصتوچهار میرساند. خروجیِ شناور الزاماً داخلِ چنین بازهٔ باریکی قرار نمیگیرد؛ کد فاصله از بازه را با تلورانسِ مطلقِ یکتریلیونیم میسنجد. خانوادهٔ کاملِ طولهای یک تا پنج از مقدارهای صفر، یک و چهار، ۳۶۳ حالت دارد و فقط یک گروه از چهارده گروه است. این شمار، پوششِ تمامِ دامنهٔ بزرگِ مجاز را ادعا نمیکند.
خروجیِ کاملِ اجرا زیر آمده است. افزون بر خانوادهٔ مرجع، پاسخِ دستی، یکنواختی، صفرها، جابهجاییِ سطلها، مقیاسِ مشترک، تفاوتِ دامنه و توان، کفگذاری، مرزهای نوع و دستنخوردنِ ورودی بررسی میشوند. همهٔ مقدارهای checks باید دقیقاً bool و درست باشند؛ تعدادِ حالتهای داخلِ یک حلقه بهعنوانِ تعدادِ گروهها گزارش نمیشود. نتیجهٔ عددیِ این اجرا، تضمینِ همهٔ سکوها یا ورودیهای بیرونِ قرارداد نیست.
{
"runtime": {
"python": "3.14.5",
"implementation": "CPython",
"dependencies": "standard library only"
},
"supplied_data": "synthetic relative power bins, not waveform/STFT output",
"domain": {
"exact_container": "tuple",
"bin_count": [
1,
8
],
"exact_value_type": "int; bool and subclasses rejected",
"relative_power_range": [
0,
1000000
]
},
"hand_power_bins": [
1,
4
],
"hand_geometric_mean": 2,
"hand_arithmetic_mean": "5/2",
"hand_exact_flatness": "4/5",
"hand_result": {
"status": "positive",
"flatness": 0.8,
"bin_count": 2,
"relative_power_sum": 5
},
"partial_zero_result": {
"status": "zero_bin",
"flatness": 0.0,
"bin_count": 2,
"relative_power_sum": 4
},
"all_zero_result": {
"status": "all_zero_undefined",
"flatness": null,
"bin_count": 2,
"relative_power_sum": 0
},
"floor_one_result": {
"status": "positive",
"flatness": 0.8,
"bin_count": 2,
"relative_power_sum": 5
},
"floored_all_zero_result": {
"status": "positive",
"flatness": 1.0,
"bin_count": 2,
"relative_power_sum": 2
},
"magnitude_counterexample": {
"status": "positive",
"flatness": 0.9428090415820634,
"bin_count": 2,
"relative_power_sum": 3
},
"largest_domain_example": {
"status": "positive",
"flatness": 0.2032319035427478,
"bin_count": 8,
"relative_power_sum": 7000001
},
"oracle": {
"algorithm": "integer product and rational-power bisection; no logs/exp",
"bisection_steps": 64,
"exact_bracket_width_maximum": "1/18446744073709551616",
"finite_cases_in_one_group": 363,
"partial_zero_cases": 296,
"all_zero_undefined_cases": 5,
"max_float_difference_to_bracket_midpoint": 1.1102230246251565e-16,
"comparison_absolute_tolerance": 1e-12,
"float_need_not_lie_inside_exact_rational_bracket": true
},
"permutation_cases_in_one_group": 24,
"invalid_power_fixtures_in_one_group": 17,
"invalid_floor_fixtures_in_same_group": 6,
"roundoff_boundary_policy": "positive computed log-ratio capped at zero, AM>=GM",
"limitations": "No FFT/STFT, librosa/SciPy, physical power, perceptual quality or classifier run",
"checks": {
"hand_geometric_two_arithmetic_five_halves_ratio_four_fifths": true,
"positive_uniform_and_single_bin_are_one": true,
"partial_zero_is_zero_but_all_zero_is_undefined": true,
"exact_integer_power_rational_brackets_finite_family_one_group": true,
"bin_permutation_preserves_unweighted_descriptor": true,
"common_positive_scale_preserves_ratio_inside_own_bounds": true,
"magnitude_and_power_representations_are_not_interchangeable": true,
"floor_is_explicit_maximum_replacement_not_additive_epsilon": true,
"floored_all_zero_becomes_one_without_redefining_raw_silence": true,
"bin_set_changes_metric_but_repeating_whole_pattern_does_not": true,
"closed_length_and_integer_power_bounds_are_computable": true,
"strict_types_containers_values_and_floor_contract_rejected": true,
"inputs_immutable_and_result_mappings_independent": true,
"all_states_use_strict_JSON_null_not_nonfinite_numbers": true
},
"unique_check_groups": 14
}
۵. چهار پرسش دربارهٔ تفسیرِ تختیِ طیف

پرسشِ اول: اگر مقدارهای یک و چهار را در سه ضرب کنیم، نسبت چه میشود؟ پاسخ: سه و دوازده، میانگینِ هندسیِ شش و میانگینِ حسابیِ پانزدهدوم میدهند؛ نسبت همچنان چهارپنجم است. این استدلال برای مقیاسِ مثبتِ مشترک و دادهٔ بدونِ کفِ ثابت است. در استفاده از تابع، حاصلِ ضرب باید داخلِ دامنهٔ صحیحِ مجاز هم باقی بماند.
پرسشِ دوم: آیا دامنههای یک و دو همان تختیِ توانهای یک و چهار را دارند؟ پاسخ: خیر؛ نسبتِ دامنهها دو ضربدر رادیکالِ دو تقسیم بر سه، حدود ۰٫۹۴۲۸ است؛ نسبتِ توانها ۰٫۸ میشود. بنابراین عوضکردنِ نمایش از دامنه به توان، تغییرِ صرفِ واحد نیست. نام و نحوهٔ تولیدِ مقادیر باید همراهِ ویژگی ذخیره شود.
پرسشِ سوم: چرا بردارِ سراسر صفر پس از کفِ یک، نسبتِ یک دارد؟ پاسخ: دادهٔ جدید یک و یک است؛ هر دو میانگین یک میشوند. دادهٔ خام هنوز نسبتِ تعریفنشده دارد. این دو پاسخ را با یک برچسبِ سکوت یا کیفیت ادغام نمیکنیم و کفِ مثبت را اندازهگیریِ نویزِ محیط معرفی نمیکنیم.
پرسشِ چهارم: نسبتِ بزرگتر، تماسِ واضحتر یا SNR بهتر را ثابت میکند؟ پاسخ: خیر؛ این توصیفگر فقط یکنواختیِ نسبیِ سطلهای انتخابشده را خلاصه میکند. مقایسهٔ صوتِ مرجع با SNR به موجِ مرجع و اختلافِ همتراز نیاز داشت و مسئلهٔ دیگری بود. فهمپذیری، خطای تشخیصِ گفتار و کیفیتِ ادراکی به داده و معیارِ متناسب با وظیفه نیاز دارند.
دامنههای دقیقِ منابع در ۲۹ مهر ۱۴۰۵ خوانده شدند: صفحهٔ منبعِ librosa نسخهٔ 1.0.0 و راهنمای SciPy نسخهٔ 1.18.0 را نشان میدادند. اینها نسخهٔ مستنداتاند و با نسخهٔ واقعیِ Python در خروجی یکی نیستند. تاریخِ نخستین انتشارِ این دو صفحه معلوم نیست؛ جستوجوی هفت و سی روزِ اخیر نیز مبنای ادعای خبرِ تازه قرار نگرفته است. مثال، آموزشِ حسابِ ویژگی است و نتیجهای دربارهٔ محصول یا مکالمهٔ واقعی نمیدهد.
منابع و مطالعهٔ بیشتر
- librosa 1.0؛ تابع کامل spectral_flatness و کفگذاریِ توان
- SciPy 1.18؛ میانگین هندسی، فرمول لگاریتمی و دامنهٔ ورودی
بررسی منابع: ۲۹ مهر ۱۴۰۵. تحلیلها و پیشنهادهای اجرایی، جمعبندی نویسندهاند.

