feat(cw): draw the whole audio band so an out-of-window tone is visible

The waterfall showed only the model's 400-1200 Hz window, so a tone outside it
was absent from the picture entirely. Measured on keyed audio, the brightest
column in that narrow view swings 1.01x between key-down and key-up against
13.76x for a tone in range - it carries no keying at all, so the operator could
not tell a signal was present, let alone where it was. Markers alone could not
fix that: they pointed at a frequency with nothing drawn there.

compute() now takes an optional bin range, defaulting to the model's own, so the
decoder path is byte-identical and the golden-vector test still holds. The
display asks for DC to Nyquist, 129 bins against 65. The FFT already computed
every bin - this only changes which are kept - so the cost is a wider copy.

The decoder window is framed and faintly lifted, since half the picture is now
outside what the model reads and nothing said which half.

Marker fixes found while reviewing the render: the tone marker was orange, which
is a colour the inferno ramp itself passes through, so a marker sitting on the
trace it pointed at was indistinguishable from the keying gaps in that trace -
invisible in exactly the case it existed for. It is cyan now, and both markers
are pips in a gutter above the spectrum rather than lines across it.

Also from the release audit:

- compute()'s bin-count guard was written as a three-term disjunction, which any
  custom range satisfies regardless of bin count, leaving the model invariant
  unenforced for the caller most able to break it. Rewritten as an implication,
  with a Nyquist bound so no range can index past the FFT output.
- signalStrength was gated on a confirmed out-of-window tone, which is false when
  detection fails - and it fails for a slow fist, measured at prominence 2.5
  against a 4.5 threshold for 15% duty. So the meter still read half scale beside
  an empty transcript. It now requires a tone confirmed decodable: 11 flow
  combinations, 3 wrong before, 0 wrong after.
- detectedToneHz never expired, so after retuning into the band the hint kept
  naming the frequency the operator had left, indefinitely. It now clears after
  10 s without a tone, which is clear of any real gap - the longest being 1.7 s
  between words at 5 WPM.
- The waterfall label read estimatedPitch while the hint read detectedToneHz, two
  numbers up to 800 Hz apart both claiming to be the tone. Both read the latter.
- Removed a redundant toFloat() that the compiler warned about.

Accessibility, untouched until now: the waterfall was a bare Canvas and the AMSAT
day cells bare Boxes, so both announced nothing at all - on the status page that
is the entire content of the screen. Both now carry a contentDescription naming
the tone or the day's worst status and report count. The AMSAT tap target goes
from 28 dp to 48 dp with the coloured tile still 28 dp, so the grid keeps its
density. Strings in all nine locales for both modules.
This commit is contained in:
mckero committed 2026-08-23 05:50:59 +00:00
1 parent 984a139a81
commit 10c415fabd
24 files changed
+364 -141

No files matched your search

@@ -175,4 +175,5 @@
<string name="amsat_no_data_legend">Sin datos</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT: una franja por franja de 2 horas</string>
<string name="prefs_other_amsat_stripes_help">Activado, cada día son doce franjas de dos horas, así se ve una interrupción dentro del día. Desactivado, cada día es un color y un recuento de informes; el color es el peor estado del día, así que un solo fallo sigue viéndose.</string>
<string name="amsat_day_desc">%1$s, %2$s, %3$d informes</string>
</resources>
@@ -93,6 +93,10 @@
\n\nPerbarui database setidaknya seminggu sekali untuk prediksi yang akurat.</string>
<string name="pass_whatsnew_title" translatable="false">Apa yang baru di Look4Sat</string>
<string name="pass_whatsnew_message" translatable="false">
* BARU: air terjun CW menandai posisi nada sebenarnya, bahkan saat di luar rentang dekoder
* BARU: satu baris di bawah air terjun menyebut nada dan apakah nada dipindahkan ke rentang
* BARU: meter sinyal CW tidak lagi tinggi untuk nada yang tak terdengar dekoder
* BARU: pilih gaya hari AMSAT di Pengaturan - dua belas garis, atau satu warna dengan jumlah laporan
* BARU: Status AMSAT menampilkan 12 garis dua jam per hari — pemadaman dalam hari kini terlihat
* BARU: Status AMSAT menggunakan hari kalender UTC, cocok dengan halaman resmi
* BARU: dua abu-abu membedakan apakah slot tidak dilaporkan atau tidak pernah diambil
@@ -113,7 +117,7 @@
* Perbaikan: perhitungan kemajuan pass dijaga terhadap pembagian dengan nol
* Perbaikan: panggilan calculatePasses bersamaan tidak lagi memicu perhitungan duplikat
* Perbaikan: pengiriman QSO duplikat WaveLog dan kondisi balapan pembaruan grid square
</string>
</string>
<string name="radar_back">Kembali</string>
<string name="radar_notify">Beri tahu</string>
<string name="radar_az_text">Azimuth</string>
@@ -308,4 +312,5 @@
<string name="amsat_no_data_legend">Tidak ada data</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT: satu garis per slot 2 jam</string>
<string name="prefs_other_amsat_stripes_help">Saat aktif, setiap hari adalah dua belas garis dua jam, sehingga pemadaman dalam satu hari terlihat. Saat mati, setiap hari adalah satu warna dan jumlah laporan - warnanya status terburuk hari itu, jadi satu kegagalan pun tetap terlihat.</string>
<string name="amsat_day_desc">%1$s, %2$s, %3$d laporan</string>
</resources>
@@ -92,6 +92,10 @@
\n\nPerbarui database setidaknya seminggu sekali untuk prediksi yang akurat.</string>
<string name="pass_whatsnew_title" translatable="false">Apa yang baru di Look4Sat</string>
<string name="pass_whatsnew_message" translatable="false">
* BARU: air terjun CW menandai posisi nada sebenarnya, bahkan saat di luar rentang dekoder
* BARU: satu baris di bawah air terjun menyebut nada dan apakah nada dipindahkan ke rentang
* BARU: meter sinyal CW tidak lagi tinggi untuk nada yang tak terdengar dekoder
* BARU: pilih gaya hari AMSAT di Pengaturan - dua belas garis, atau satu warna dengan jumlah laporan
* BARU: Status AMSAT menampilkan 12 garis dua jam per hari — pemadaman dalam hari kini terlihat
* BARU: Status AMSAT menggunakan hari kalender UTC, cocok dengan halaman resmi
* BARU: dua abu-abu membedakan apakah slot tidak dilaporkan atau tidak pernah diambil
@@ -112,7 +116,7 @@
* Perbaikan: perhitungan kemajuan pass dijaga terhadap pembagian dengan nol
* Perbaikan: panggilan calculatePasses bersamaan tidak lagi memicu perhitungan duplikat
* Perbaikan: pengiriman QSO duplikat WaveLog dan kondisi balapan pembaruan grid square
</string>
</string>
<string name="radar_back">Kembali</string>
<string name="radar_notify">Beri tahu</string>
<string name="radar_az_text">Azimuth</string>
@@ -308,4 +312,5 @@
<string name="amsat_no_data_legend">Tidak ada data</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT: satu garis per slot 2 jam</string>
<string name="prefs_other_amsat_stripes_help">Saat aktif, setiap hari adalah dua belas garis dua jam, sehingga pemadaman dalam satu hari terlihat. Saat mati, setiap hari adalah satu warna dan jumlah laporan - warnanya status terburuk hari itu, jadi satu kegagalan pun tetap terlihat.</string>
<string name="amsat_day_desc">%1$s, %2$s, %3$d laporan</string>
</resources>
@@ -175,4 +175,5 @@
<string name="amsat_no_data_legend">Нет данных</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT: полоса на каждые 2 часа</string>
<string name="prefs_other_amsat_stripes_help">Включено — каждый день это двенадцать двухчасовых полос, поэтому перерыв внутри дня виден. Выключено — каждый день это один цвет и число отчётов; цвет соответствует худшему состоянию за день, так что даже один сбой остаётся заметен.</string>
<string name="amsat_day_desc">%1$s, %2$s, отчётов: %3$d</string>
</resources>
@@ -175,4 +175,5 @@
<string name="amsat_no_data_legend">දත්ත නැත</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT: පැය 2 කට එක තීරුවක්</string>
<string name="prefs_other_amsat_stripes_help">සක්‍රිය විට සෑම දිනයක් පැය දෙකේ තීරු දොළහකි, එබැවින් දිනක් තුළ ඇති බිඳවැටීම දැකිය හැක. අක්‍රිය විට සෑම දිනයක් එක් වර්ණයක් සහ වාර්තා ගණනකි — වර්ණය එදින නරකම තත්ත්වයයි, එබැවින් එක් අසාර්ථකත්වයක් වුවද පෙනේ.</string>
<string name="amsat_day_desc">%1$s, %2$s, වාර්තා %3$d</string>
</resources>
@@ -97,6 +97,10 @@
\n\nDoğru tahminler alabilmek için veritabanını en az haftada bir güncelleyin.</string>
<string name="pass_whatsnew_title" translatable="false">What\'s new in Look4Sat</string>
<string name="pass_whatsnew_message" translatable="false">
* YENİ: CW şelalesi, tonunuz çözücü aralığının dışında olsa bile gerçek yerini işaretler
* YENİ: şelalenin altındaki satır tonu adlandırır ve aralığa taşınıp taşınmadığını söyler
* YENİ: çözücünün duyamadığı bir ton için CW sinyal göstergesi artık yüksek okumuyor
* YENİ: AMSAT gün stilini Ayarlar\'dan seçin - on iki şerit veya rapor sayılı tek renk
* YENİ: AMSAT durumu günde 12 iki saatlik şerit gösterir — gün içi kesintiler görünür
* YENİ: AMSAT durumu UTC takvim günlerini kullanır, resmi sayfayla eşleşir
* YENİ: iki gri, bir yuvanın rapor edilmediğini mi yoksa hiç alınmadığını mı ayırt eder
@@ -117,7 +121,7 @@
* Düzeltme: geçiş ilerleme hesaplaması sıfıra bölme durumuna karşı korumalı
* Düzeltme: eşzamanlı calculatePasses çağrıları artık yinelenen hesaplamaları tetiklemiyor
* Düzeltme: WaveLog yinelenen QSO gönderimleri ve ızgara kare güncellemesi yarış durumları
</string>
</string>
<!-- Radar screen -->
<string name="radar_back">Geri</string>
@@ -320,4 +324,5 @@
<string name="amsat_no_data_legend">Veri yok</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT: 2 saatlik dilim başına şerit</string>
<string name="prefs_other_amsat_stripes_help">Açıkken her gün on iki iki saatlik şerittir, böylece gün içindeki kesinti görünür. Kapalıyken her gün tek renk ve rapor sayısıdır; renk günün en kötü durumudur, yani tek bir arıza bile görünür kalır.</string>
<string name="amsat_day_desc">%1$s, %2$s, %3$d rapor</string>
</resources>
@@ -175,4 +175,5 @@
<string name="amsat_no_data_legend">Немає даних</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT: смуга на кожні 2 години</string>
<string name="prefs_other_amsat_stripes_help">Увімкнено — кожен день це дванадцять двогодинних смуг, тож перерва всередині дня видна. Вимкнено — кожен день це один колір і кількість звітів; колір відповідає найгіршому стану за день, тож навіть один збій залишається помітним.</string>
<string name="amsat_day_desc">%1$s, %2$s, звітів: %3$d</string>
</resources>
@@ -89,6 +89,10 @@
<string name="pass_welcome_message">请务必在设置中通过GPS、经纬度或QTH定位您的位置\n建议至少每周更新一次数据库,以确保预测结果的准确性</string>
<string name="pass_whatsnew_title">Look4Sat Pro 更新内容</string>
<string name="pass_whatsnew_message" translatable="false">
* 新: CW 瀑布图标出音调真实位置, 即使它在解码范围之外
* 新: 瀑布图下方一行文字说明音调频率, 以及是否已搬入解码范围
* 新: 解码范围外的音调不再让信号强度条显示高值
* 新: 设置里可选 AMSAT 日格样式 —— 12 条纹, 或单色加报告数
* 新: AMSAT 状态页每天显示 12 条两小时条纹,当日内的中断一目了然
* 新: AMSAT 状态页改用 UTC 日历日, 与官方页面一致
* 新: 两种灰色区分"无人上报"和"无数据"
@@ -109,7 +113,7 @@
* 修复: 过境进度计算防除零崩溃
* 修复: 并发 calculatePasses 调用不再触发重复计算
* 修复: WaveLog 重复提交 QSO 与网格更新竞态
</string>
</string>
<!-- Radar screen -->
<string name="radar_back">后退</string>
@@ -310,4 +314,5 @@
<string name="amsat_no_data_legend">无数据</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT:每 2 小时一条纹</string>
<string name="prefs_other_amsat_stripes_help">开启时每天画成 12 条两小时条纹,一天之内的中断也看得见。关闭时每天显示一个颜色和报告总数——颜色取当天最差状态,所以出现过一次故障也不会被藏起来。</string>
<string name="amsat_day_desc">%1$s,%2$s,%3$d 条报告</string>
</resources>
@@ -101,10 +101,10 @@
\n\nPlease update the database at least weekly to get accurate predictions.</string>
<string name="pass_whatsnew_title" translatable="false">What\'s new in Look4Sat</string>
<string name="pass_whatsnew_message" translatable="false">
* NEW: AMSAT status shows 12 two-hour stripes per day — outages inside a day are now visible
* NEW: AMSAT status uses UTC calendar days, matching the official page
* NEW: two greys tell you whether a slot had no report or was never fetched
* NEW: a data-coverage marker shows when quieter satellites are crowded out of the global pull
* NEW: the CW waterfall marks where your tone really is, even when it sits outside the decoder\'s range
* NEW: a line under the CW waterfall names the tone and says whether it is being moved into range
* NEW: the CW signal meter no longer reads high for a tone the decoder cannot actually hear
* NEW: choose the AMSAT day style in Settings - twelve stripes, or one colour with a report count
* NEW: AMSAT status shows 12 two-hour stripes per day — outages inside a day are now visible
* NEW: AMSAT status uses UTC calendar days, matching the official page
* NEW: two greys tell you whether a slot had no report or was never fetched
@@ -125,7 +125,7 @@
* Fixed: pass progress calculation guards against division by zero
* Fixed: concurrent calculatePasses calls no longer trigger duplicate calculations
* Fixed: WaveLog duplicate QSO submissions and grid square update race conditions
</string>
</string>
<!-- Radar screen -->
<string name="radar_back">Back</string>
@@ -347,4 +347,5 @@
<string name="amsat_no_data_legend">No data</string>
<string name="prefs_other_switch_amsat_stripes">AMSAT: stripe per 2-hour slot</string>
<string name="prefs_other_amsat_stripes_help">On, each day is twelve two-hour stripes, so an outage inside a day is visible. Off, each day is one colour and a report count - the colour is the day\'s worst status, so a single failure still shows.</string>
<string name="amsat_day_desc">%1$s, %2$s, %3$d reports</string>
</resources>