mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-06 23:02:42 +02:00
Merge branch 'master' into head
This commit is contained in:
commit
699b9d0517
1
.gitignore
vendored
1
.gitignore
vendored
@ -177,6 +177,7 @@ win/Debug
|
||||
win/Release
|
||||
win/Projects/*/Debug
|
||||
win/Projects/*/Release
|
||||
win/.vs/
|
||||
|
||||
# All those help files
|
||||
help/manual*
|
||||
|
@ -70,7 +70,9 @@ public:
|
||||
sampleCount ( int v ) : value { v } {}
|
||||
sampleCount ( unsigned v ) : value { v } {}
|
||||
sampleCount ( long v ) : value { v } {}
|
||||
sampleCount ( unsigned long v ) : value { v } {}
|
||||
|
||||
// unsigned long is 64 bit on some platforms. Let it narrow.
|
||||
sampleCount ( unsigned long v ) : value ( v ) {}
|
||||
|
||||
// Beware implicit conversions from floating point values!
|
||||
// Otherwise the meaning of binary operators with sampleCount change
|
||||
|
549
locale/ca.po
549
locale/ca.po
File diff suppressed because it is too large
Load Diff
@ -3,10 +3,10 @@
|
||||
# Antonio Paniagua Navarro <aplist@gmail.com>, 2011, 2012, 2013, 2014, 2015, 2016.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Audacity 2.0.x\n"
|
||||
"Project-Id-Version: Audacity 2.2.x\n"
|
||||
"Report-Msgid-Bugs-To: audacity-translation@lists.sourceforge.net\n"
|
||||
"POT-Creation-Date: 2017-03-18 18:41+0000\n"
|
||||
"PO-Revision-Date: 2016-11-22 17:44+0100\n"
|
||||
"PO-Revision-Date: 2017-03-30 02:21-0000\n"
|
||||
"Last-Translator: Antonio Paniagua Navarro <aplist@gmail.com>\n"
|
||||
"Language-Team: Spanish <audacity-translation@lists.sourceforge.net>\n"
|
||||
"Language: es\n"
|
||||
@ -14,7 +14,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
"X-Generator: Poedit 1.6.9\n"
|
||||
|
||||
#: lib-src/FileDialog/gtk/FileDialogPrivate.cpp:75
|
||||
#, c-format
|
||||
@ -3812,7 +3812,7 @@ msgstr "Pistas seleccionadas silenciadas durante %.2f segundos en %.2f"
|
||||
|
||||
#: src/Menus.cpp:4772 src/effects/Silence.h:22
|
||||
msgid "Silence"
|
||||
msgstr "Silenciar"
|
||||
msgstr "Silencio"
|
||||
|
||||
#: src/Menus.cpp:4803
|
||||
msgid "Duplicated"
|
||||
|
12
locale/it.po
12
locale/it.po
@ -2218,8 +2218,8 @@ msgid ""
|
||||
"More:</b> Visit our [[http://wiki.audacityteam.org/index.php|Wiki]] for "
|
||||
"tips, tricks, extra tutorials and effects plug-ins."
|
||||
msgstr ""
|
||||
"Di piiù:</b> Visita il nostro [[http://wiki.audacityteam.org/index.php|"
|
||||
"Wiki]] per suggerimenti, trucchi, altri tutorial plug-in effetti."
|
||||
"Di più:</b> Visita il nostro [[http://wiki.audacityteam.org/index.php|"
|
||||
"Wiki]] per suggerimenti, trucchi, altri tutorial ed effetti audio."
|
||||
|
||||
#: src/HelpText.cpp:223
|
||||
msgid ""
|
||||
@ -3646,7 +3646,7 @@ msgstr "Nessuna traccia etichetta"
|
||||
|
||||
#: src/Menus.cpp:2716
|
||||
msgid "no label track at or below focused track"
|
||||
msgstr "nessuna etiichetta traccia nella o sotto la traccia evidenziata"
|
||||
msgstr "nessuna etichetta traccia nella o sotto la traccia evidenziata"
|
||||
|
||||
#: src/Menus.cpp:2749
|
||||
msgid "no labels in label track"
|
||||
@ -8228,7 +8228,7 @@ msgstr "I passi per blocco sono troppo pochi per i tipi finestra."
|
||||
|
||||
#: src/effects/NoiseReduction.cpp:585
|
||||
msgid "Steps per block cannot exceed the window size."
|
||||
msgstr "I passi per blocco non possono superare la dimensione finestra."
|
||||
msgstr "I passi per blocco non possono superare la dimensione della finestra."
|
||||
|
||||
#: src/effects/NoiseReduction.cpp:590
|
||||
msgid "Median method is not implemented for more than four steps per window."
|
||||
@ -11258,7 +11258,7 @@ msgid ""
|
||||
"Error while writing %s file (disk full?).\n"
|
||||
"Libsndfile says \"%s\""
|
||||
msgstr ""
|
||||
"Errore nella scrittura del file %s (diisco pienol?).\n"
|
||||
"Errore durante la scrittura del file %s (disco pieno?).\n"
|
||||
"Libsndfile indica \"%s\""
|
||||
|
||||
#: src/import/Import.cpp:508
|
||||
@ -12386,7 +12386,7 @@ msgstr "Dispositivo:"
|
||||
|
||||
#: src/prefs/MidiIOPrefs.cpp:146
|
||||
msgid "MIDI Synthesizer Latency (ms):"
|
||||
msgstr "Latenza Sintetiizzatore MIDI (ms):"
|
||||
msgstr "Latenza Sintetizzatore MIDI (ms):"
|
||||
|
||||
#: src/prefs/MidiIOPrefs.cpp:184
|
||||
msgid "No MIDI interfaces"
|
||||
|
1278
locale/ru.po
1278
locale/ru.po
File diff suppressed because it is too large
Load Diff
47
locale/uk.po
47
locale/uk.po
@ -9,7 +9,7 @@ msgstr ""
|
||||
"Project-Id-Version: Audacity 2.0.0\n"
|
||||
"Report-Msgid-Bugs-To: audacity-translation@lists.sourceforge.net\n"
|
||||
"POT-Creation-Date: 2017-03-18 18:41+0000\n"
|
||||
"PO-Revision-Date: 2017-02-13 19:31+0200\n"
|
||||
"PO-Revision-Date: 2017-03-21 19:14+0200\n"
|
||||
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
|
||||
"Language-Team: Ukrainian <translation@linux.org.ua>\n"
|
||||
"Language: uk\n"
|
||||
@ -423,7 +423,7 @@ msgstr "Зупинити скрипт"
|
||||
|
||||
#: src/AboutDialog.cpp:94
|
||||
msgid "Check Online"
|
||||
msgstr ""
|
||||
msgstr "У інтернеті"
|
||||
|
||||
#: src/AboutDialog.cpp:103
|
||||
msgid "quality assurance"
|
||||
@ -1136,9 +1136,8 @@ msgid "Could not enumerate files in auto save directory."
|
||||
msgstr "Неможливо скласти список файлів у теці автозбереження."
|
||||
|
||||
#: src/AutoRecovery.cpp:760
|
||||
#, fuzzy
|
||||
msgid "Error Decoding File"
|
||||
msgstr "Помилка під час спроби декодування файла"
|
||||
msgstr "Помилка під час декодування файла"
|
||||
|
||||
#: src/BatchCommandDialog.cpp:60 src/BatchCommandDialog.cpp:64
|
||||
#: src/BatchCommandDialog.cpp:65
|
||||
@ -1486,9 +1485,8 @@ msgstr ""
|
||||
"іншу теку для тимчасових файлів у діалоговому вікні налаштовування програми."
|
||||
|
||||
#: src/DirManager.cpp:424
|
||||
#, fuzzy
|
||||
msgid "Cleaning project temporary files"
|
||||
msgstr "Вилучення тимчасових файлів"
|
||||
msgstr "Вилучаємо тимчасові файли проекту"
|
||||
|
||||
#: src/DirManager.cpp:437
|
||||
msgid "Cleaning up temporary files"
|
||||
@ -2169,25 +2167,32 @@ msgstr "Відсутня локальна довідка"
|
||||
|
||||
#: src/HelpText.cpp:198
|
||||
msgid "Get the Official Released Version of Audacity"
|
||||
msgstr ""
|
||||
msgstr "Отримати офіційну випущену версію Audacity"
|
||||
|
||||
#: src/HelpText.cpp:200
|
||||
msgid ""
|
||||
"<br><br>The version of Audacity you are using is an <b>Alpha test version</"
|
||||
"b>."
|
||||
msgstr ""
|
||||
"<br><br>Версія Audacity, якою ви користуєтеся є <b>попередньою тестовою "
|
||||
"версією (Alpha)</b>."
|
||||
|
||||
#: src/HelpText.cpp:201
|
||||
msgid ""
|
||||
"We strongly recommend that you use our latest stable released version, which "
|
||||
"has full documentation and support.<br><br>"
|
||||
msgstr ""
|
||||
"Ми наполегливо рекомендуємо вам скористатися найсвіжішою стабільною версією "
|
||||
"програми, яку повністю документовано і яка супроводжується розробниками.<br><"
|
||||
"br>"
|
||||
|
||||
#: src/HelpText.cpp:202
|
||||
msgid ""
|
||||
"You can help us get Audacity ready for release by joining our [[http://www."
|
||||
"audacityteam.org/community/|community]].<hr><br><br>"
|
||||
msgstr ""
|
||||
"Ви можете допомогти нам поліпшити Audacity до випуску, долучившись до нашої "
|
||||
"[[http://www.audacityteam.org/community/|community]].<hr><br><br>"
|
||||
|
||||
#: src/HelpText.cpp:205
|
||||
msgid "How to get help"
|
||||
@ -2516,9 +2521,8 @@ msgstr ""
|
||||
"%s (%s)."
|
||||
|
||||
#: src/Legacy.cpp:263
|
||||
#, fuzzy
|
||||
msgid "Error Converting Legacy Project File"
|
||||
msgstr "Помилка під час спроби збереження файла проекту"
|
||||
msgstr "Помилка під час спроби перетворити застарілий файл проекту"
|
||||
|
||||
#: src/Legacy.cpp:304
|
||||
#, c-format
|
||||
@ -9709,17 +9713,15 @@ msgstr ""
|
||||
"до кодування Latin-1]"
|
||||
|
||||
#: src/effects/nyquist/Nyquist.cpp:1638
|
||||
#, fuzzy, c-format
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Bad Nyquist 'control' type specification: '%s' in plug-in file '%s'.\n"
|
||||
"Control not created."
|
||||
msgstr ""
|
||||
"Помилкова специфікація керування «control» Nyquist: «%s» у файлі додатка "
|
||||
"«%s».\n"
|
||||
"Керування не створено."
|
||||
"Помилкова специфікація керування «control» Nyquist: «%s» у файлі додатка «%"
|
||||
"s».\nКерування не створено."
|
||||
|
||||
#: src/effects/nyquist/Nyquist.cpp:1746
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Your code looks like SAL syntax, but there is no 'return' statement.\n"
|
||||
"For SAL, use a return statement such as:\n"
|
||||
@ -9729,11 +9731,9 @@ msgid ""
|
||||
" ."
|
||||
msgstr ""
|
||||
"Синтаксичні конструкції вашого коду нагадують SAL, але не вказано інструкції "
|
||||
"return. Вам слід або скористатися інструкцією return ось так:\n"
|
||||
"\treturn s * 0.1\n"
|
||||
"для SAL, або почати з дужки, ось так:\n"
|
||||
"\t(mult s 0.1)\n"
|
||||
"як це робиться у LISP."
|
||||
"return. Вам слід або скористатися інструкцією return ось так:\n\treturn "
|
||||
"*track* * 0.1\nдля SAL, або почати з дужки, ось так:\n\t(mult *track* "
|
||||
"0.1)\nяк це робиться у LISP."
|
||||
|
||||
#: src/effects/nyquist/Nyquist.cpp:1749
|
||||
msgid "Error in Nyquist code"
|
||||
@ -9945,9 +9945,8 @@ msgid "Error writing to file: \"%s\""
|
||||
msgstr "Помилка під час спроби записати дані до файла «%s»"
|
||||
|
||||
#: src/effects/VST/VSTEffect.cpp:3565
|
||||
#, fuzzy
|
||||
msgid "Error Saving Effect Presets"
|
||||
msgstr "Помилка під час спроби збереження шаблону VST"
|
||||
msgstr "Помилка під час спроби зберегти шаблони ефектів"
|
||||
|
||||
#: src/effects/VST/VSTEffect.cpp:3686
|
||||
#, c-format
|
||||
@ -10303,9 +10302,8 @@ msgstr "Відкрити вікно нетипових параметрів фо
|
||||
|
||||
#: src/export/ExportFFmpegDialogs.cpp:498
|
||||
#: src/export/ExportFFmpegDialogs.cpp:522
|
||||
#, fuzzy
|
||||
msgid "Error Saving FFmpeg Presets"
|
||||
msgstr "Помилка під час спроби збереження шаблону VST"
|
||||
msgstr "Помилка під час спроби зберегти шаблони FFmpeg"
|
||||
|
||||
#: src/export/ExportFFmpegDialogs.cpp:568
|
||||
#, c-format
|
||||
@ -14283,9 +14281,8 @@ msgid "NaN"
|
||||
msgstr "Не число"
|
||||
|
||||
#: src/widgets/numformatter.cpp:146
|
||||
#, fuzzy
|
||||
msgid "Infinity"
|
||||
msgstr "-Нескінченність"
|
||||
msgstr "Нескінченність"
|
||||
|
||||
#: src/widgets/numformatter.cpp:150
|
||||
msgid "-Infinity"
|
||||
|
294
locale/zh_CN.po
294
locale/zh_CN.po
@ -12,7 +12,7 @@ msgstr ""
|
||||
"Project-Id-Version: Audacity\n"
|
||||
"Report-Msgid-Bugs-To: audacity-translation@lists.sourceforge.net\n"
|
||||
"POT-Creation-Date: 2017-03-18 18:41+0000\n"
|
||||
"PO-Revision-Date: 2016-07-03 12:19+0000\n"
|
||||
"PO-Revision-Date: 2017-03-27 15:01+0800\n"
|
||||
"Last-Translator: zhangmin <zm1990s@gmail.com>\n"
|
||||
"Language-Team: Chinese (http://www.transifex.com/klyok/audacity/language/"
|
||||
"zh/)\n"
|
||||
@ -21,6 +21,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 1.8.12\n"
|
||||
|
||||
#: lib-src/FileDialog/gtk/FileDialogPrivate.cpp:75
|
||||
#, c-format
|
||||
@ -39,17 +40,16 @@ msgstr "请选择一个已存在的文件。"
|
||||
#: src/AutoRecovery.cpp:195 src/Menus.cpp:4294 src/Menus.cpp:4306
|
||||
#: src/Menus.cpp:7005 src/Menus.cpp:7084 src/Project.cpp:3124
|
||||
#: src/Project.cpp:5118 src/Project.cpp:5137 src/TimerRecordDialog.cpp:471
|
||||
#: src/TimerRecordDialog.cpp:649 src/TrackPanel.cpp:8489
|
||||
#: src/WaveTrack.cpp:1316 src/WaveTrack.cpp:1335 src/WaveTrack.cpp:2487
|
||||
#: src/effects/Contrast.cpp:56 src/effects/Contrast.cpp:75
|
||||
#: src/effects/Contrast.cpp:82 src/effects/Contrast.cpp:96
|
||||
#: src/effects/Effect.cpp:2584 src/effects/Generator.cpp:59
|
||||
#: src/effects/nyquist/Nyquist.cpp:411 src/export/ExportFFmpeg.cpp:842
|
||||
#: src/export/ExportMP2.cpp:229 src/prefs/DirectoriesPrefs.cpp:210
|
||||
#: src/prefs/DirectoriesPrefs.cpp:239 src/prefs/KeyConfigPrefs.cpp:509
|
||||
#: src/prefs/KeyConfigPrefs.cpp:523 src/prefs/KeyConfigPrefs.cpp:548
|
||||
#: src/prefs/KeyConfigPrefs.cpp:1038 src/toolbars/ControlToolBar.cpp:686
|
||||
#: src/toolbars/ControlToolBar.cpp:1122
|
||||
#: src/TimerRecordDialog.cpp:649 src/TrackPanel.cpp:8489 src/WaveTrack.cpp:1316
|
||||
#: src/WaveTrack.cpp:1335 src/WaveTrack.cpp:2487 src/effects/Contrast.cpp:56
|
||||
#: src/effects/Contrast.cpp:75 src/effects/Contrast.cpp:82
|
||||
#: src/effects/Contrast.cpp:96 src/effects/Effect.cpp:2584
|
||||
#: src/effects/Generator.cpp:59 src/effects/nyquist/Nyquist.cpp:411
|
||||
#: src/export/ExportFFmpeg.cpp:842 src/export/ExportMP2.cpp:229
|
||||
#: src/prefs/DirectoriesPrefs.cpp:210 src/prefs/DirectoriesPrefs.cpp:239
|
||||
#: src/prefs/KeyConfigPrefs.cpp:509 src/prefs/KeyConfigPrefs.cpp:523
|
||||
#: src/prefs/KeyConfigPrefs.cpp:548 src/prefs/KeyConfigPrefs.cpp:1038
|
||||
#: src/toolbars/ControlToolBar.cpp:686 src/toolbars/ControlToolBar.cpp:1122
|
||||
msgid "Error"
|
||||
msgstr "错误"
|
||||
|
||||
@ -179,14 +179,12 @@ msgstr "脚本"
|
||||
msgid "Output"
|
||||
msgstr "输出"
|
||||
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1051
|
||||
#: src/effects/nyquist/Nyquist.cpp:2214
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1051 src/effects/nyquist/Nyquist.cpp:2214
|
||||
msgid "Load Nyquist script"
|
||||
msgstr "加载 Nyquist 脚本"
|
||||
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1054
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1100
|
||||
#: src/effects/nyquist/Nyquist.cpp:2239
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1100 src/effects/nyquist/Nyquist.cpp:2239
|
||||
msgid "Nyquist scripts (*.ny)|*.ny|Lisp scripts (*.lsp)|*.lsp|All files|*"
|
||||
msgstr "Nyquist 脚本 (*.ny)|*.ny|Lisp 脚本 (*.lsp)|*.lsp|所有文件|*"
|
||||
|
||||
@ -204,8 +202,7 @@ msgstr "脚本未被保存。"
|
||||
msgid "Warning"
|
||||
msgstr "警告"
|
||||
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1097
|
||||
#: src/effects/nyquist/Nyquist.cpp:2236
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1097 src/effects/nyquist/Nyquist.cpp:2236
|
||||
msgid "Save Nyquist script"
|
||||
msgstr "保存 Nyquist 脚本"
|
||||
|
||||
@ -223,11 +220,11 @@ msgstr "Tango 图标库 (工具栏图标)"
|
||||
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1417
|
||||
msgid "Leland Lucius"
|
||||
msgstr "Leland Lucius"
|
||||
msgstr "利兰卢修斯\\N"
|
||||
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1418
|
||||
msgid "(C) 2009 by Leland Lucius"
|
||||
msgstr "(C) 2009 by Leland Lucius"
|
||||
msgstr "(C) 2009 by 利兰卢修斯\\N"
|
||||
|
||||
#: lib-src/mod-nyq-bench/NyqBench.cpp:1419
|
||||
msgid ""
|
||||
@ -423,7 +420,7 @@ msgstr "停止脚本"
|
||||
|
||||
#: src/AboutDialog.cpp:94
|
||||
msgid "Check Online"
|
||||
msgstr ""
|
||||
msgstr "在线检查"
|
||||
|
||||
#: src/AboutDialog.cpp:103
|
||||
msgid "quality assurance"
|
||||
@ -431,7 +428,7 @@ msgstr "质量保证"
|
||||
|
||||
#: src/AboutDialog.cpp:104
|
||||
msgid "system administration"
|
||||
msgstr ""
|
||||
msgstr "系统管理\\N"
|
||||
|
||||
#: src/AboutDialog.cpp:105 src/AboutDialog.cpp:108 src/AboutDialog.cpp:110
|
||||
#: src/AboutDialog.cpp:112 src/AboutDialog.cpp:118 src/AboutDialog.cpp:120
|
||||
@ -457,28 +454,28 @@ msgstr "包络线"
|
||||
|
||||
#: src/AboutDialog.cpp:106 src/AboutDialog.cpp:127
|
||||
msgid "co-founder and developer"
|
||||
msgstr ""
|
||||
msgstr "联合创始人和开发者\\N"
|
||||
|
||||
#: src/AboutDialog.cpp:109 src/AboutDialog.cpp:113 src/AboutDialog.cpp:131
|
||||
#: src/AboutDialog.cpp:132
|
||||
msgid "documentation and support"
|
||||
msgstr ""
|
||||
msgstr "文档和支持\\N"
|
||||
|
||||
#: src/AboutDialog.cpp:119
|
||||
msgid "documentation and support, French"
|
||||
msgstr ""
|
||||
msgstr "文档和支持,法语"
|
||||
|
||||
#: src/AboutDialog.cpp:137
|
||||
msgid "accessibility advisor"
|
||||
msgstr ""
|
||||
msgstr "无障碍顾问"
|
||||
|
||||
#: src/AboutDialog.cpp:156
|
||||
msgid "graphic artist"
|
||||
msgstr ""
|
||||
msgstr "图形艺术家\\N"
|
||||
|
||||
#: src/AboutDialog.cpp:163
|
||||
msgid "composer"
|
||||
msgstr ""
|
||||
msgstr "作曲家\\N"
|
||||
|
||||
#: src/AboutDialog.cpp:166
|
||||
#, fuzzy
|
||||
@ -513,7 +510,6 @@ msgstr ""
|
||||
"\">Audacity</a>支持Windows、Mac OS X和GNU/Linux(以及其它的Unix类操作系统)。"
|
||||
|
||||
#: src/AboutDialog.cpp:337
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"If you find a bug or have a suggestion for us, please write, in English, to "
|
||||
"our [[mailto:feedback@audacityteam.org|feedback address]]. For help, view "
|
||||
@ -522,8 +518,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"如果你找到一个bug或者有建议给我们,请用英语书写,发邮件到 <a href=\"mailto:"
|
||||
"feedback@audacityteam.org\">反馈地址</a>。如果想获得帮助,查看小贴士和小技"
|
||||
"巧,请访问<a href=\"http://wiki.audacityteam.org/\">wiki</a> 或 <a href="
|
||||
"\"http://forum.audacityteam.org/\">论坛</a>。"
|
||||
"巧,请访问<a href=\"http://wiki.audacityteam.org/\">audacity维基</a> 或 <a "
|
||||
"href=\"http://forum.audacityteam.org/\">audacity论坛</a>。"
|
||||
|
||||
#. i18n-hint: The translation of "translator_credits" will appear
|
||||
#. * in the credits in the About Audacity window. Use this to add
|
||||
@ -555,11 +551,11 @@ msgstr "Audacity开发人员"
|
||||
|
||||
#: src/AboutDialog.cpp:368
|
||||
msgid "Emeritus:"
|
||||
msgstr ""
|
||||
msgstr "名誉:"
|
||||
|
||||
#: src/AboutDialog.cpp:369
|
||||
msgid "Distinguished Audacity Team members, not currently active"
|
||||
msgstr ""
|
||||
msgstr "杰出的Audacity团队成员,目前不活跃"
|
||||
|
||||
#: src/AboutDialog.cpp:372
|
||||
#, fuzzy
|
||||
@ -567,9 +563,8 @@ msgid "Contributors"
|
||||
msgstr "其他贡献者"
|
||||
|
||||
#: src/AboutDialog.cpp:375
|
||||
#, fuzzy
|
||||
msgid "Translators"
|
||||
msgstr "播录"
|
||||
msgstr "翻译"
|
||||
|
||||
#: src/AboutDialog.cpp:379 src/prefs/LibraryPrefs.cpp:49
|
||||
msgid "Libraries"
|
||||
@ -596,6 +591,7 @@ msgid ""
|
||||
"Audacity website: [[http://www.audacityteam.org/|http://www.audacityteam."
|
||||
"org/]]"
|
||||
msgstr ""
|
||||
"Audacity网站:[[http://www.audacityteam.org/|http://www.audacityteam.org/]]"
|
||||
|
||||
#. i18n-hint: Information about when audacity was compiled
|
||||
#: src/AboutDialog.cpp:446 src/AboutDialog.cpp:459 src/AboutDialog.cpp:631
|
||||
@ -760,7 +756,7 @@ msgstr "文件丢失"
|
||||
#: src/AudacityApp.cpp:1047
|
||||
#, c-format
|
||||
msgid "Language \"%s\" is unknown"
|
||||
msgstr ""
|
||||
msgstr "语言 \"%s\"未知"
|
||||
|
||||
#: src/AudacityApp.cpp:1170
|
||||
msgid "Report generated to:"
|
||||
@ -939,8 +935,8 @@ msgstr "Audacity日志"
|
||||
msgid "&Save..."
|
||||
msgstr "保存...(&S)"
|
||||
|
||||
#: src/AudacityLogger.cpp:199 src/Tags.cpp:883
|
||||
#: src/prefs/KeyConfigPrefs.cpp:273 src/prefs/KeyConfigPrefs.cpp:781
|
||||
#: src/AudacityLogger.cpp:199 src/Tags.cpp:883 src/prefs/KeyConfigPrefs.cpp:273
|
||||
#: src/prefs/KeyConfigPrefs.cpp:781
|
||||
msgid "Cl&ear"
|
||||
msgstr "清除(&e)"
|
||||
|
||||
@ -2119,25 +2115,27 @@ msgstr "没有本地帮助"
|
||||
|
||||
#: src/HelpText.cpp:198
|
||||
msgid "Get the Official Released Version of Audacity"
|
||||
msgstr ""
|
||||
msgstr "获得Audacity的官方发布版本"
|
||||
|
||||
#: src/HelpText.cpp:200
|
||||
msgid ""
|
||||
"<br><br>The version of Audacity you are using is an <b>Alpha test version</"
|
||||
"b>."
|
||||
msgstr ""
|
||||
msgstr "<br><br>您所使用的Audacity版本是 <b>内部测试版</b>."
|
||||
|
||||
#: src/HelpText.cpp:201
|
||||
msgid ""
|
||||
"We strongly recommend that you use our latest stable released version, which "
|
||||
"has full documentation and support.<br><br>"
|
||||
msgstr ""
|
||||
msgstr "我们强烈建议您使用我们最新的稳定版本,它具有完整的文档和支持。<br><br>"
|
||||
|
||||
#: src/HelpText.cpp:202
|
||||
msgid ""
|
||||
"You can help us get Audacity ready for release by joining our [[http://www."
|
||||
"audacityteam.org/community/|community]].<hr><br><br>"
|
||||
msgstr ""
|
||||
"您可以通过加入我们来帮助我们让Audacity准备发布 [[http://www.audacityteam.org/"
|
||||
"community/|audacity社区]].<hr><br><br>"
|
||||
|
||||
#: src/HelpText.cpp:205
|
||||
#, fuzzy
|
||||
@ -2305,12 +2303,12 @@ msgstr "指定新文件名:"
|
||||
#. i18n-hint: An opening parenthesis, in some languages a right parenthesis
|
||||
#: src/Internat.cpp:265
|
||||
msgid "("
|
||||
msgstr ""
|
||||
msgstr "("
|
||||
|
||||
#. i18n-hint: A closing parenthesis, in some languages a left parenthesis
|
||||
#: src/Internat.cpp:267
|
||||
msgid ")"
|
||||
msgstr ""
|
||||
msgstr ")"
|
||||
|
||||
#: src/LabelDialog.cpp:102
|
||||
msgid "Edit Labels"
|
||||
@ -2732,7 +2730,7 @@ msgstr "光标移至音轨末(&E)"
|
||||
|
||||
#: src/Menus.cpp:561
|
||||
msgid "Cursor to Stored &Cursor Position"
|
||||
msgstr ""
|
||||
msgstr "游标存储光标位置"
|
||||
|
||||
#: src/Menus.cpp:567
|
||||
msgid "In All &Tracks"
|
||||
@ -2768,15 +2766,15 @@ msgstr "到音轨结束点(&E)"
|
||||
|
||||
#: src/Menus.cpp:600
|
||||
msgid "Store Re&gion"
|
||||
msgstr ""
|
||||
msgstr "存储区域"
|
||||
|
||||
#: src/Menus.cpp:603
|
||||
msgid "Retrieve Regio&n"
|
||||
msgstr ""
|
||||
msgstr "检索区域&n"
|
||||
|
||||
#: src/Menus.cpp:606
|
||||
msgid "Store Cursor Pos&ition"
|
||||
msgstr ""
|
||||
msgstr "存储光标位置"
|
||||
|
||||
#: src/Menus.cpp:614
|
||||
msgid "Pla&y Region"
|
||||
@ -2976,7 +2974,7 @@ msgstr "追加录音(&d)"
|
||||
|
||||
#: src/Menus.cpp:788
|
||||
msgid "Pinned Recording/Playback &Head"
|
||||
msgstr ""
|
||||
msgstr "固定录音/播放头"
|
||||
|
||||
#: src/Menus.cpp:793
|
||||
msgid "&Overdub (on/off)"
|
||||
@ -3115,7 +3113,7 @@ msgstr "编辑标记(&E)"
|
||||
|
||||
#: src/Menus.cpp:931
|
||||
msgid "&Type to Create a Label (on/off)"
|
||||
msgstr ""
|
||||
msgstr "&键入以创建标签(开/关)"
|
||||
|
||||
#: src/Menus.cpp:938
|
||||
msgid "S&ort Tracks"
|
||||
@ -3185,7 +3183,7 @@ msgstr "缩放"
|
||||
|
||||
#: src/Menus.cpp:1055
|
||||
msgid "&Bring All to Front"
|
||||
msgstr ""
|
||||
msgstr "全部带到前面"
|
||||
|
||||
#: src/Menus.cpp:1066 src/Menus.cpp:1069 src/effects/Contrast.cpp:298
|
||||
msgid "&Help"
|
||||
@ -4105,7 +4103,7 @@ msgid ""
|
||||
"Timer Recording cannot be used with more than one open project.\n"
|
||||
"\n"
|
||||
"Please close any additional projects and try again."
|
||||
msgstr ""
|
||||
msgstr "定时录制不能与多个打开的项目一起使用。请关闭任何其他项目,然后重试。"
|
||||
|
||||
#: src/Menus.cpp:6547 src/Menus.cpp:6558 src/TimerRecordDialog.cpp:658
|
||||
#, fuzzy
|
||||
@ -4117,7 +4115,7 @@ msgid ""
|
||||
"Timer Recording cannot be used while you have unsaved changes.\n"
|
||||
"\n"
|
||||
"Please save or close this project and try again."
|
||||
msgstr ""
|
||||
msgstr "在保存更改时,无法使用定时录像。请保存或关闭此项目,然后重试。"
|
||||
|
||||
#: src/Menus.cpp:6731
|
||||
msgid "Edited labels"
|
||||
@ -4817,7 +4815,7 @@ msgstr "删除轨道"
|
||||
|
||||
#: src/Project.cpp:5605
|
||||
msgid "Less than 1 minute"
|
||||
msgstr ""
|
||||
msgstr "不到1分钟"
|
||||
|
||||
#. i18n-hint: A time in hours and minutes. Only translate the "and".
|
||||
#: src/Project.cpp:5618
|
||||
@ -5299,7 +5297,7 @@ msgstr "持续时间错误"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:374
|
||||
msgid "Automatic Save path is invalid."
|
||||
msgstr ""
|
||||
msgstr "自动保存路径无效。"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:375
|
||||
#, fuzzy
|
||||
@ -5308,7 +5306,7 @@ msgstr "持续时间错误"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:381
|
||||
msgid "Automatic Export path is invalid."
|
||||
msgstr ""
|
||||
msgstr "自动导出路径无效。"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:382
|
||||
#, fuzzy
|
||||
@ -5317,7 +5315,7 @@ msgstr "持续时间错误"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:419
|
||||
msgid "Timer Recording Disk Space Warning"
|
||||
msgstr ""
|
||||
msgstr "计时器记录磁盘空间通知"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:461 src/TimerRecordDialog.cpp:869
|
||||
#, fuzzy
|
||||
@ -5343,11 +5341,11 @@ msgstr "录制结束"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:528 src/TimerRecordDialog.cpp:1006
|
||||
msgid "Automatic Save enabled:\n"
|
||||
msgstr ""
|
||||
msgstr "自动保存启用:\n"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:529 src/TimerRecordDialog.cpp:1007
|
||||
msgid "Automatic Export enabled:\n"
|
||||
msgstr ""
|
||||
msgstr "自动导出启用:\n"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:530 src/TimerRecordDialog.cpp:1008
|
||||
#: src/TimerRecordDialog.cpp:1051
|
||||
@ -5449,7 +5447,7 @@ msgstr "选项:"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:900
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "什么都不做"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:901
|
||||
#, fuzzy
|
||||
@ -5458,11 +5456,11 @@ msgstr "退出 Audacity"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:902
|
||||
msgid "Restart system"
|
||||
msgstr ""
|
||||
msgstr "重启系统"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:903
|
||||
msgid "Shutdown system"
|
||||
msgstr ""
|
||||
msgstr "关机系统"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:913
|
||||
#, fuzzy
|
||||
@ -5483,7 +5481,7 @@ msgstr "录制音频"
|
||||
msgid ""
|
||||
"Scheduled to stop at:\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
msgstr "计划停在:\n"
|
||||
|
||||
#: src/TimerRecordDialog.cpp:1024
|
||||
msgid "Audacity Timer Record - Waiting for Start"
|
||||
@ -5578,7 +5576,7 @@ msgstr "格式(&F)"
|
||||
|
||||
#: src/TrackPanel.cpp:640
|
||||
msgid "Rat&e"
|
||||
msgstr ""
|
||||
msgstr "Rat&e"
|
||||
|
||||
#: src/TrackPanel.cpp:645
|
||||
msgid "Up &Octave"
|
||||
@ -5651,13 +5649,13 @@ msgstr "单击在垂直方向放大,按住Shift键单击缩小,拖拽创建
|
||||
#: src/TrackPanel.cpp:1410
|
||||
#, c-format
|
||||
msgid "%s to select or deselect track. Drag up or down to change track order."
|
||||
msgstr ""
|
||||
msgstr "%s选择或取消选择轨道。向上或向下拖动以更改轨道顺序。"
|
||||
|
||||
#. i18n-hint: %s is replaced by (translation of) 'Ctrl-Click' on windows, 'Command-Click' on Mac
|
||||
#: src/TrackPanel.cpp:1417
|
||||
#, c-format
|
||||
msgid "%s to select or deselect track."
|
||||
msgstr ""
|
||||
msgstr "%s选择或取消选择轨道。"
|
||||
|
||||
#: src/TrackPanel.cpp:1432
|
||||
msgid "Click and drag to adjust relative size of stereo tracks."
|
||||
@ -5910,10 +5908,12 @@ msgid ""
|
||||
"To change Spectrogram Settings, stop any\n"
|
||||
".playing or recording first."
|
||||
msgstr ""
|
||||
"要更改谱图设置,请停止任何\n"
|
||||
"播放或录音."
|
||||
|
||||
#: src/TrackPanel.cpp:8200
|
||||
msgid "Stop the Audio First"
|
||||
msgstr ""
|
||||
msgstr "先停止音频"
|
||||
|
||||
#: src/TrackPanel.cpp:8294
|
||||
#, c-format
|
||||
@ -6304,7 +6304,7 @@ msgstr "高音"
|
||||
|
||||
#: src/effects/BassTreble.cpp:47
|
||||
msgid "Link Sliders"
|
||||
msgstr ""
|
||||
msgstr "链接滑块"
|
||||
|
||||
#: src/effects/BassTreble.cpp:92
|
||||
#, fuzzy
|
||||
@ -6313,7 +6313,7 @@ msgstr "选区的左端收缩"
|
||||
|
||||
#: src/effects/BassTreble.cpp:209
|
||||
msgid "Tone controls"
|
||||
msgstr ""
|
||||
msgstr "音调控制"
|
||||
|
||||
#: src/effects/BassTreble.cpp:218
|
||||
#, fuzzy
|
||||
@ -6339,7 +6339,7 @@ msgstr "电平"
|
||||
|
||||
#: src/effects/BassTreble.cpp:261
|
||||
msgid "&Link Volume control to Tone controls"
|
||||
msgstr ""
|
||||
msgstr "&并将音量控制连接到音调控制"
|
||||
|
||||
#: src/effects/BassTreble.h:26
|
||||
msgid "Bass and Treble"
|
||||
@ -6352,7 +6352,7 @@ msgstr "百分比"
|
||||
|
||||
#: src/effects/ChangePitch.cpp:58 src/effects/ChangeTempo.cpp:52
|
||||
msgid "SBSMS"
|
||||
msgstr ""
|
||||
msgstr "吕雪莉"
|
||||
|
||||
#: src/effects/ChangePitch.cpp:126
|
||||
msgid "Change the pitch of a track without changing its tempo"
|
||||
@ -6360,7 +6360,7 @@ msgstr "改变音高,维持节奏不变"
|
||||
|
||||
#: src/effects/ChangePitch.cpp:188
|
||||
msgid "High Quality Pitch Change"
|
||||
msgstr ""
|
||||
msgstr "高质量的音高变化"
|
||||
|
||||
#: src/effects/ChangePitch.cpp:245
|
||||
msgid "Change Pitch without Changing Tempo"
|
||||
@ -6430,7 +6430,7 @@ msgstr "改变百分比"
|
||||
|
||||
#: src/effects/ChangePitch.cpp:331 src/effects/ChangeTempo.cpp:278
|
||||
msgid "Use high quality stretching (slow)"
|
||||
msgstr ""
|
||||
msgstr "使用高品质的拉伸 (慢)"
|
||||
|
||||
#: src/effects/ChangePitch.h:39
|
||||
msgid "Change Pitch"
|
||||
@ -6716,7 +6716,7 @@ msgstr "一次只能测量一个音轨。"
|
||||
msgid ""
|
||||
"Invalid audio selection.\n"
|
||||
"Please ensure that audio is selected."
|
||||
msgstr ""
|
||||
msgstr "音频选择无效请确保选择音频。"
|
||||
|
||||
#: src/effects/Contrast.cpp:82
|
||||
msgid ""
|
||||
@ -6813,7 +6813,7 @@ msgstr "背景结束时间"
|
||||
|
||||
#: src/effects/Contrast.cpp:380
|
||||
msgid "Background higher than foreground"
|
||||
msgstr ""
|
||||
msgstr "背景高于前景"
|
||||
|
||||
#: src/effects/Contrast.cpp:383
|
||||
msgid "WCAG2 Pass"
|
||||
@ -6972,19 +6972,19 @@ msgstr "确认覆盖"
|
||||
|
||||
#: src/effects/Distortion.cpp:65
|
||||
msgid "Hard Overdrive"
|
||||
msgstr ""
|
||||
msgstr "硬盘超速:"
|
||||
|
||||
#: src/effects/Distortion.cpp:66
|
||||
msgid "Cubic Curve (odd harmonics)"
|
||||
msgstr ""
|
||||
msgstr "立方曲线(奇次谐波)"
|
||||
|
||||
#: src/effects/Distortion.cpp:67
|
||||
msgid "Even Harmonics"
|
||||
msgstr ""
|
||||
msgstr "甚至谐波"
|
||||
|
||||
#: src/effects/Distortion.cpp:68
|
||||
msgid "Expand and Compress"
|
||||
msgstr ""
|
||||
msgstr "展开和压缩"
|
||||
|
||||
#: src/effects/Distortion.cpp:69 src/effects/Leveller.h:21
|
||||
msgid "Leveller"
|
||||
@ -6992,11 +6992,11 @@ msgstr "水平器"
|
||||
|
||||
#: src/effects/Distortion.cpp:70
|
||||
msgid "Rectifier Distortion"
|
||||
msgstr ""
|
||||
msgstr "整流器失真"
|
||||
|
||||
#: src/effects/Distortion.cpp:71
|
||||
msgid "Hard Limiter 1413"
|
||||
msgstr ""
|
||||
msgstr "硬限制1413"
|
||||
|
||||
#: src/effects/Distortion.cpp:78 src/effects/Noise.cpp:48
|
||||
msgid "Type"
|
||||
@ -7004,7 +7004,7 @@ msgstr "类型"
|
||||
|
||||
#: src/effects/Distortion.cpp:79
|
||||
msgid "DC Block"
|
||||
msgstr ""
|
||||
msgstr "直流块"
|
||||
|
||||
#: src/effects/Distortion.cpp:80
|
||||
#, fuzzy
|
||||
@ -7029,84 +7029,84 @@ msgstr "重复"
|
||||
#: src/effects/Distortion.cpp:102
|
||||
#, no-c-format
|
||||
msgid "Hard clip -12dB, 80% make-up gain"
|
||||
msgstr ""
|
||||
msgstr "硬夹80%增益12dB,化妆"
|
||||
|
||||
#: src/effects/Distortion.cpp:104
|
||||
#, no-c-format
|
||||
msgid "Soft clip -12dB, 80% make-up gain"
|
||||
msgstr ""
|
||||
msgstr "软夹80%增益12dB,化妆"
|
||||
|
||||
#: src/effects/Distortion.cpp:105
|
||||
msgid "Fuzz Box"
|
||||
msgstr ""
|
||||
msgstr "绒盒"
|
||||
|
||||
#: src/effects/Distortion.cpp:106
|
||||
msgid "Walkie-talkie"
|
||||
msgstr ""
|
||||
msgstr "对讲机"
|
||||
|
||||
#: src/effects/Distortion.cpp:107
|
||||
msgid "Blues drive sustain"
|
||||
msgstr ""
|
||||
msgstr "布鲁斯驱动支持"
|
||||
|
||||
#: src/effects/Distortion.cpp:108
|
||||
msgid "Light Crunch Overdrive"
|
||||
msgstr ""
|
||||
msgstr "光紧缩超速"
|
||||
|
||||
#: src/effects/Distortion.cpp:109
|
||||
msgid "Heavy Overdrive"
|
||||
msgstr ""
|
||||
msgstr "重超速"
|
||||
|
||||
#: src/effects/Distortion.cpp:110
|
||||
msgid "3rd Harmonic (Perfect Fifth)"
|
||||
msgstr ""
|
||||
msgstr "第三谐波(完美第五)"
|
||||
|
||||
#: src/effects/Distortion.cpp:111
|
||||
msgid "Valve Overdrive"
|
||||
msgstr ""
|
||||
msgstr "阀驱动"
|
||||
|
||||
#: src/effects/Distortion.cpp:112
|
||||
msgid "2nd Harmonic (Octave)"
|
||||
msgstr ""
|
||||
msgstr "第二谐波(倍频程)"
|
||||
|
||||
#: src/effects/Distortion.cpp:113
|
||||
msgid "Gated Expansion Distortion"
|
||||
msgstr ""
|
||||
msgstr "门控膨胀变形"
|
||||
|
||||
#: src/effects/Distortion.cpp:114
|
||||
msgid "Leveller, Light, -70dB noise floor"
|
||||
msgstr ""
|
||||
msgstr "矫直机、光、70分贝噪声地板"
|
||||
|
||||
#: src/effects/Distortion.cpp:115
|
||||
msgid "Leveller, Moderate, -70dB noise floor"
|
||||
msgstr ""
|
||||
msgstr "矫直机,温和,70分贝噪声地板"
|
||||
|
||||
#: src/effects/Distortion.cpp:116
|
||||
msgid "Leveller, Heavy, -70dB noise floor"
|
||||
msgstr ""
|
||||
msgstr "矫直机,重,70分贝噪声地板"
|
||||
|
||||
#: src/effects/Distortion.cpp:117
|
||||
msgid "Leveller, Heavier, -70dB noise floor"
|
||||
msgstr ""
|
||||
msgstr "矫直机,重,70分贝噪声地板"
|
||||
|
||||
#: src/effects/Distortion.cpp:118
|
||||
msgid "Leveller, Heaviest, -70dB noise floor"
|
||||
msgstr ""
|
||||
msgstr "矫直机,重,70分贝噪声地板"
|
||||
|
||||
#: src/effects/Distortion.cpp:119
|
||||
msgid "Half-wave Rectifier"
|
||||
msgstr ""
|
||||
msgstr "半波整流"
|
||||
|
||||
#: src/effects/Distortion.cpp:120
|
||||
msgid "Full-wave Rectifier"
|
||||
msgstr ""
|
||||
msgstr "全波整流"
|
||||
|
||||
#: src/effects/Distortion.cpp:121
|
||||
msgid "Full-wave Rectifier (DC blocked)"
|
||||
msgstr ""
|
||||
msgstr "全波整流器(直流阻塞)"
|
||||
|
||||
#: src/effects/Distortion.cpp:122
|
||||
msgid "Percussion Limiter"
|
||||
msgstr ""
|
||||
msgstr "冲击器"
|
||||
|
||||
#: src/effects/Distortion.cpp:127
|
||||
#, fuzzy
|
||||
@ -7120,7 +7120,7 @@ msgstr "要添加的重复次数:"
|
||||
|
||||
#: src/effects/Distortion.cpp:192
|
||||
msgid "Waveshaping distortion effect"
|
||||
msgstr ""
|
||||
msgstr "波形失真影响"
|
||||
|
||||
#: src/effects/Distortion.cpp:344
|
||||
#, fuzzy
|
||||
@ -7129,7 +7129,7 @@ msgstr "插值类型"
|
||||
|
||||
#: src/effects/Distortion.cpp:348
|
||||
msgid "DC blocking filter"
|
||||
msgstr ""
|
||||
msgstr "直流阻断滤波器"
|
||||
|
||||
#: src/effects/Distortion.cpp:355
|
||||
#, fuzzy
|
||||
@ -7148,11 +7148,11 @@ msgstr "破音"
|
||||
|
||||
#: src/effects/Distortion.cpp:676
|
||||
msgid "Drive"
|
||||
msgstr ""
|
||||
msgstr "驱动"
|
||||
|
||||
#: src/effects/Distortion.cpp:677 src/effects/Distortion.cpp:691
|
||||
msgid "Make-up Gain"
|
||||
msgstr ""
|
||||
msgstr "弥补增益"
|
||||
|
||||
#: src/effects/Distortion.cpp:688
|
||||
#, fuzzy
|
||||
@ -7161,14 +7161,14 @@ msgstr "静音阈值"
|
||||
|
||||
#: src/effects/Distortion.cpp:690
|
||||
msgid "Hardness"
|
||||
msgstr ""
|
||||
msgstr "硬度"
|
||||
|
||||
#: src/effects/Distortion.cpp:704 src/effects/Distortion.cpp:718
|
||||
#: src/effects/Distortion.cpp:732 src/effects/Distortion.cpp:746
|
||||
#: src/effects/Distortion.cpp:760 src/effects/Distortion.cpp:774
|
||||
#: src/effects/Distortion.cpp:802
|
||||
msgid "Distortion amount"
|
||||
msgstr ""
|
||||
msgstr "变形量"
|
||||
|
||||
#: src/effects/Distortion.cpp:705 src/effects/Distortion.cpp:719
|
||||
#: src/effects/Distortion.cpp:733 src/effects/Distortion.cpp:747
|
||||
@ -7184,11 +7184,11 @@ msgstr "减小处理时间。"
|
||||
|
||||
#: src/effects/Distortion.cpp:761
|
||||
msgid "Harmonic brightness"
|
||||
msgstr ""
|
||||
msgstr "谐波的亮度"
|
||||
|
||||
#: src/effects/Distortion.cpp:788
|
||||
msgid "Levelling fine adjustment"
|
||||
msgstr ""
|
||||
msgstr "平微调"
|
||||
|
||||
#: src/effects/Distortion.cpp:790
|
||||
#, fuzzy
|
||||
@ -7197,7 +7197,7 @@ msgstr "调平度:"
|
||||
|
||||
#: src/effects/Distortion.cpp:814
|
||||
msgid "dB Limit"
|
||||
msgstr ""
|
||||
msgstr "分贝限制"
|
||||
|
||||
#: src/effects/Distortion.cpp:816
|
||||
#, fuzzy
|
||||
@ -7211,17 +7211,17 @@ msgstr "保留噪音(&u)"
|
||||
|
||||
#: src/effects/Distortion.cpp:833
|
||||
msgid " (Not Used):"
|
||||
msgstr ""
|
||||
msgstr "(未使用):"
|
||||
|
||||
#. i18n-hint: Control range.
|
||||
#: src/effects/Distortion.cpp:838
|
||||
msgid " (-100 to 0 dB):"
|
||||
msgstr ""
|
||||
msgstr "(- 100至0分贝):"
|
||||
|
||||
#. i18n-hint: Control range.
|
||||
#: src/effects/Distortion.cpp:853
|
||||
msgid " (-80 to -20 dB):"
|
||||
msgstr ""
|
||||
msgstr "(- 80至20分贝):"
|
||||
|
||||
#. i18n-hint: Control range.
|
||||
#: src/effects/Distortion.cpp:864 src/effects/Distortion.cpp:875
|
||||
@ -7232,7 +7232,7 @@ msgstr "(%) [-50到100]:"
|
||||
#. i18n-hint: Control range.
|
||||
#: src/effects/Distortion.cpp:886
|
||||
msgid " (0 to 5):"
|
||||
msgstr ""
|
||||
msgstr "(0至5):"
|
||||
|
||||
#: src/effects/Distortion.h:26
|
||||
#, fuzzy
|
||||
@ -7315,7 +7315,7 @@ msgstr "一遍遍地重复选中音频"
|
||||
#: src/effects/Echo.cpp:102 src/effects/FindClipping.cpp:168
|
||||
#: src/effects/Paulstretch.cpp:249
|
||||
msgid "Requested value exceeds memory capacity."
|
||||
msgstr ""
|
||||
msgstr "请求值超过内存容量。"
|
||||
|
||||
#: src/effects/Echo.cpp:159
|
||||
msgid "Delay time (seconds):"
|
||||
@ -7341,6 +7341,8 @@ msgid ""
|
||||
"\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
"%s:无法加载下面的设置。将使用默认设置。\n"
|
||||
"%s"
|
||||
|
||||
#. i18n-hint: Name of time display format that shows time in hours,
|
||||
#. * minutes, seconds and samples (at the current project sample rate)
|
||||
@ -7702,7 +7704,7 @@ msgstr "如果想应用均衡器,所有选择的轨道必须拥有相同的采
|
||||
|
||||
#: src/effects/Equalization.cpp:490
|
||||
msgid "Track sample rate is too low for this effect."
|
||||
msgstr ""
|
||||
msgstr "跟踪采样率太低,这种效果。"
|
||||
|
||||
#: src/effects/Equalization.cpp:491
|
||||
#, fuzzy
|
||||
@ -8052,7 +8054,7 @@ msgstr "淡出"
|
||||
|
||||
#: src/effects/FindClipping.cpp:61
|
||||
msgid "Creates labels where clipping is detected"
|
||||
msgstr ""
|
||||
msgstr "创建剪切检测到的标签"
|
||||
|
||||
#: src/effects/FindClipping.cpp:98
|
||||
msgid "Clipping"
|
||||
@ -8563,6 +8565,9 @@ msgid ""
|
||||
"Try increasing the audio selection to at least %.1f seconds,\n"
|
||||
"or reducing the 'Time Resolution' to less than %.1f seconds."
|
||||
msgstr ""
|
||||
"音频选择太短,无法预览。\n"
|
||||
"尝试增加音频选择至少 %.1f seconds,\n"
|
||||
" 或减少时间分辨率''小于 %.1f seconds."
|
||||
|
||||
#. i18n-hint: 'Time Resolution' is the name of a control in the Paulstretch effect.
|
||||
#: src/effects/Paulstretch.cpp:291
|
||||
@ -8573,6 +8578,8 @@ msgid ""
|
||||
"For the current audio selection, the maximum\n"
|
||||
"'Time Resolution' is %.1f seconds."
|
||||
msgstr ""
|
||||
"无法预览。\n"
|
||||
"'Time Resolution' is %.1f seconds."
|
||||
|
||||
#. i18n-hint: 'Time Resolution' is the name of a control in the Paulstretch effect.
|
||||
#: src/effects/Paulstretch.cpp:300
|
||||
@ -8583,6 +8590,9 @@ msgid ""
|
||||
"Try increasing the audio selection to at least %.1f seconds,\n"
|
||||
"or reducing the 'Time Resolution' to less than %.1f seconds."
|
||||
msgstr ""
|
||||
"选择的时间分辨率太长。\n"
|
||||
"尝试增加音频选择至少 %.1f seconds,\n"
|
||||
"或减少“时间分辨率”小于 %.1f seconds."
|
||||
|
||||
#: src/effects/Paulstretch.h:19
|
||||
msgid "Paulstretch"
|
||||
@ -8878,7 +8888,7 @@ msgstr "反向"
|
||||
|
||||
#: src/effects/SBSMSEffect.h:38
|
||||
msgid "SBSMS Time / Pitch Stretch"
|
||||
msgstr ""
|
||||
msgstr "吕雪莉时间/沥青拉伸"
|
||||
|
||||
#. i18n-hint: Butterworth is the name of the person after whom the filter type is named.
|
||||
#: src/effects/ScienFilter.cpp:92
|
||||
@ -9187,11 +9197,11 @@ msgstr "插值"
|
||||
|
||||
#: src/effects/ToneGen.cpp:132
|
||||
msgid "Generates an ascending or descending tone of one of four types"
|
||||
msgstr ""
|
||||
msgstr "产生四种类型之一的升序或降序"
|
||||
|
||||
#: src/effects/ToneGen.cpp:133
|
||||
msgid "Generates a constant frequency tone of one of four types"
|
||||
msgstr ""
|
||||
msgstr "产生四种类型之一的恒定频率音调"
|
||||
|
||||
#: src/effects/ToneGen.cpp:312
|
||||
msgid "Waveform:"
|
||||
@ -9268,7 +9278,7 @@ msgstr "自动减小指定音量以下片段的长度"
|
||||
msgid ""
|
||||
"When truncating independently, there may only be one selected audio track in "
|
||||
"each Sync-Locked Track Group."
|
||||
msgstr ""
|
||||
msgstr "当独立截断时,每个同步锁定的轨道组中只能有一个选定的音轨。"
|
||||
|
||||
#: src/effects/TruncSilence.cpp:702
|
||||
msgid "Detect Silence"
|
||||
@ -9549,6 +9559,8 @@ msgid ""
|
||||
"in the track Spectrogram settings and select the\n"
|
||||
"frequency range for the effect to act on."
|
||||
msgstr ""
|
||||
"要使用“光谱效应”,请在轨道光谱图设置中启用“光谱选择”,并选择要作用的效果的频"
|
||||
"率范围。"
|
||||
|
||||
#: src/effects/nyquist/Nyquist.cpp:621
|
||||
msgid ""
|
||||
@ -10798,7 +10810,7 @@ msgstr "立体声"
|
||||
|
||||
#: src/export/ExportMP3.cpp:427
|
||||
msgid "Force export to mono"
|
||||
msgstr ""
|
||||
msgstr "强制输出到单声道"
|
||||
|
||||
#. i18n-hint: LAME is the name of an MP3 converter and should not be translated
|
||||
#: src/export/ExportMP3.cpp:593
|
||||
@ -11741,7 +11753,7 @@ msgstr "不可用 - 上面的位置不存在"
|
||||
#: src/prefs/DirectoriesPrefs.cpp:208
|
||||
#, c-format
|
||||
msgid "Directory %s is not suitable (at risk of being cleaned out)"
|
||||
msgstr ""
|
||||
msgstr "目录 %s是不合适的 (冒被清理的危险)"
|
||||
|
||||
#: src/prefs/DirectoriesPrefs.cpp:216
|
||||
#, c-format
|
||||
@ -12732,11 +12744,11 @@ msgstr "轨道编号"
|
||||
|
||||
#: src/prefs/RecordingPrefs.cpp:159
|
||||
msgid "Add System &Date"
|
||||
msgstr ""
|
||||
msgstr "添加系统和日期"
|
||||
|
||||
#: src/prefs/RecordingPrefs.cpp:163
|
||||
msgid "Add System T&ime"
|
||||
msgstr ""
|
||||
msgstr "添加系统T&ime"
|
||||
|
||||
#: src/prefs/RecordingPrefs.cpp:170
|
||||
msgid "Automated Recording Level Adjustment"
|
||||
@ -13084,7 +13096,7 @@ msgstr "频谱图(&S)"
|
||||
|
||||
#: src/prefs/TracksPrefs.cpp:107
|
||||
msgid "&Pinned Recording/Playback head"
|
||||
msgstr ""
|
||||
msgstr "&固定录音/播放头"
|
||||
|
||||
#: src/prefs/TracksPrefs.cpp:110
|
||||
#, fuzzy
|
||||
@ -13135,7 +13147,7 @@ msgstr "编辑一段会移动 其它片段(&M)"
|
||||
|
||||
#: src/prefs/TracksPrefs.cpp:159
|
||||
msgid "&Type to create a label"
|
||||
msgstr ""
|
||||
msgstr "&键入以创建标签"
|
||||
|
||||
#: src/prefs/TracksPrefs.cpp:163
|
||||
msgid "Enable scrolling left of &zero"
|
||||
@ -13175,7 +13187,7 @@ msgstr "导出时混合到立体声(&S)"
|
||||
|
||||
#: src/prefs/WarningsPrefs.cpp:72
|
||||
msgid "Mixing down on export (&Custom FFmpeg or external program)"
|
||||
msgstr ""
|
||||
msgstr "混合导出(定制ffmpeg或外部程序)"
|
||||
|
||||
#: src/prefs/WarningsPrefs.cpp:75
|
||||
msgid "&Importing uncompressed audio files"
|
||||
@ -13459,7 +13471,7 @@ msgstr "启动脚本"
|
||||
#.
|
||||
#: src/toolbars/ScrubbingToolBar.cpp:170
|
||||
msgid "Stop Seeking"
|
||||
msgstr ""
|
||||
msgstr "停止寻求"
|
||||
|
||||
#: src/toolbars/ScrubbingToolBar.cpp:171
|
||||
#, fuzzy
|
||||
@ -13468,11 +13480,11 @@ msgstr "开始监视"
|
||||
|
||||
#: src/toolbars/ScrubbingToolBar.cpp:177
|
||||
msgid "Hide Scrub Ruler"
|
||||
msgstr ""
|
||||
msgstr "隐藏磨砂标尺"
|
||||
|
||||
#: src/toolbars/ScrubbingToolBar.cpp:178
|
||||
msgid "Show Scrub Ruler"
|
||||
msgstr ""
|
||||
msgstr "显示磨砂标尺"
|
||||
|
||||
#: src/toolbars/SelectionBar.cpp:88 src/toolbars/SelectionBar.cpp:303
|
||||
msgid "Selection"
|
||||
@ -13620,7 +13632,7 @@ msgstr "跟随播放"
|
||||
|
||||
#: src/tracks/ui/Scrubbing.cpp:243
|
||||
msgid "See&k"
|
||||
msgstr ""
|
||||
msgstr "See&k"
|
||||
|
||||
#: src/tracks/ui/Scrubbing.cpp:243
|
||||
#, fuzzy
|
||||
@ -14198,27 +14210,27 @@ msgstr "点击并拖动以缩放工具栏"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2089
|
||||
msgid "Click & move to Scrub. Click & drag to Seek."
|
||||
msgstr ""
|
||||
msgstr "点击和移动到擦洗。点击拖动寻找。"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2101
|
||||
msgid "Move to Seek"
|
||||
msgstr ""
|
||||
msgstr "去寻找"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2103
|
||||
msgid "Move to Scrub"
|
||||
msgstr ""
|
||||
msgstr "移动擦洗"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2110
|
||||
msgid "Drag to Seek. Release to stop seeking."
|
||||
msgstr ""
|
||||
msgstr "拖动寻找。释放停止寻求。"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2112
|
||||
msgid "Drag to Seek. Release and move to Scrub."
|
||||
msgstr ""
|
||||
msgstr "拖动寻求。释放并移动到"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2115
|
||||
msgid "Move to Scrub. Drag to Seek."
|
||||
msgstr ""
|
||||
msgstr "移动磨砂拖动寻求。"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2133
|
||||
msgid "Timeline actions disabled during recording"
|
||||
@ -14234,11 +14246,11 @@ msgstr "快速播放已启用"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2840
|
||||
msgid "Pinned Record/Play head"
|
||||
msgstr ""
|
||||
msgstr "固定录音/播放头"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2841
|
||||
msgid "Unpinned Record/Play head"
|
||||
msgstr ""
|
||||
msgstr "解除记录/播放头"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2881
|
||||
msgid "Disable Quick-Play"
|
||||
@ -14282,7 +14294,7 @@ msgstr "解锁播放区域"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2913
|
||||
msgid "Disable Scrub Ruler"
|
||||
msgstr ""
|
||||
msgstr "禁用磨砂标尺"
|
||||
|
||||
#: src/widgets/Ruler.cpp:2915
|
||||
#, fuzzy
|
||||
|
@ -1,141 +1,100 @@
|
||||
;nyquist plug-in
|
||||
;version 1
|
||||
;version 4
|
||||
;type process
|
||||
;preview enabled
|
||||
;categories "http://audacityteam.org/namespace#NoiseRemoval"
|
||||
;name "Clip Fix..."
|
||||
;action "Reconstructing clips..."
|
||||
;author "Benjamin Schwartz"
|
||||
;author "Benjamin Schwartz and Steve Daulton"
|
||||
;copyright "Licensing confirmed under terms of the GNU General Public License version 2"
|
||||
|
||||
;; clipfix.ny by Benjamin Schwartz.
|
||||
;; Licensing confirmed under terms of the GNU General Public License version 2:
|
||||
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
;; with kind agreement of Benjamin Schwartz, December 2011.
|
||||
;; GUI updated by Steve Daulton July 2012
|
||||
;;
|
||||
;; For information about writing and modifying Nyquist plug-ins:
|
||||
;; http://wiki.audacityteam.org/wiki/Nyquist_Plug-ins_Reference
|
||||
;; Algorithm by Benjamin Schwartz
|
||||
;; Clip Fix is a simple, stupid (but not blind) digital-clipping-corrector
|
||||
;; The algorithm is fairly simple:
|
||||
;; 1. Find all clipped regions
|
||||
;; 2. Get the slope immediately on either side of the region
|
||||
;; 3. Do a cubic spline interpolation.
|
||||
;; 4. Go to next region
|
||||
|
||||
;control thresh "Threshold of Clipping (%)" real "" 95 0 100
|
||||
;control threshold "Threshold of Clipping (%)" float "" 95 0 100
|
||||
;control gain "Reduce amplitude to allow for restored peaks (dB)" float "" -9 -30 0
|
||||
|
||||
(setf largenumber 100000000) ;;Largest number of samples that can be imported
|
||||
(setf blocksize 100000)
|
||||
|
||||
;;Clip Fix is a simple, stupid (but not blind) digital-clipping-corrector
|
||||
;;The algorithm is fairly simple:
|
||||
;;1. Find all clipped regions
|
||||
;;2. Get the slope immediately on either side of the region
|
||||
;;3. Do a cubic spline interpolation.
|
||||
;;4. Go to next region
|
||||
|
||||
;;Coded from start (didn't know lisp (well, scheme, but not not lisp and certainly not
|
||||
;;some XLISP 2.0 derivative)) to finish
|
||||
;;(fully working, more or less) in one afternoon (and some evening).
|
||||
;;Written by Benjamin Schwartz, MIT class of 2006, on May 25, 2004.
|
||||
;;Explanatory text added by Gale Andrews, May 2008.
|
||||
|
||||
(defun declip (sin) ;;Central function
|
||||
(let* ((threshold (* (peak sin largenumber) thresh 0.01))
|
||||
(s2 (snd-copy sin))
|
||||
(samplerate (snd-srate s2))
|
||||
(s2length (snd-length s2 largenumber)))
|
||||
|
||||
(seqrep (i (1+ (/ s2length blocksize)))
|
||||
(let ((l (min blocksize (- s2length (* i blocksize)))))
|
||||
;;(print (list i t0 l samplerate))
|
||||
(snd-from-array 0 samplerate
|
||||
(workhorse
|
||||
;;(let () (print (list s2 (type-of s2) l (type-of l)))
|
||||
(snd-fetch-array s2 l l)
|
||||
;;)
|
||||
threshold))))
|
||||
|
||||
;;(setf r (snd-fetch-array (snd-copy s) (snd-length s largenumber) 1)) ;;Create a sound array
|
||||
;;(snd-from-array (snd-t0 s) (snd-srate s) (workhorse r threshold))
|
||||
))
|
||||
|
||||
(defun workhorse (r threshold)
|
||||
|
||||
(setf n (length r)) ;; Record its length
|
||||
|
||||
(setf exithigh ()) ;;Times when the wavefrom left the allowed region
|
||||
(setf returnhigh ()) ;;Times when it returned to the allowed region
|
||||
|
||||
(setf drange 4)
|
||||
|
||||
(let ((i drange) (max (- n drange))) ;;Leave room at ends for derivative processing
|
||||
(while (< i max)
|
||||
(if (>= (aref r i) threshold)
|
||||
(if (< (aref r (- i 1)) threshold)
|
||||
(setq exithigh (cons (- i 1) exithigh))) ;;We just crossed the threshold up
|
||||
(if (>= (aref r (- i 1)) threshold)
|
||||
(setq returnhigh (cons i returnhigh)))) ;;We just crossed the threshold down
|
||||
(setq i (1+ i))))
|
||||
|
||||
(setq exithigh (reverse exithigh)) ;;List comes out backwards
|
||||
(setq returnhigh (reverse returnhigh))
|
||||
|
||||
(if (>= (aref r (1- drange)) threshold) ;;If the audio begins in a clipped region, ignore
|
||||
(setq returnhigh (cdr returnhigh))) ;the extra return from threshold
|
||||
|
||||
(setf exitlow ()) ;; Same as above, but for the bottom threshold
|
||||
(setf returnlow ())
|
||||
|
||||
(setf threshlow (* -1 threshold)) ;;Assumes your digital range is zero-centered
|
||||
(setf threshold (/ threshold 100))
|
||||
(setf gain (db-to-linear gain))
|
||||
(setf buffersize 100000)
|
||||
(setf slopelength 4) ; number of samples used to calculate the exit / re-entry slope
|
||||
|
||||
|
||||
(let ((i drange) (max (- n drange)))
|
||||
(while (< i max)
|
||||
(if (<= (aref r i) threshlow)
|
||||
(if (> (aref r (- i 1)) threshlow)
|
||||
(setq exitlow (cons (- i 1) exitlow)))
|
||||
(if (<= (aref r (- i 1)) threshlow)
|
||||
(setq returnlow (cons i returnlow))))
|
||||
(setq i (1+ i))))
|
||||
(defun declip (sig thresh peak)
|
||||
(let* ((threshold (* thresh peak))
|
||||
(ln (truncate len))
|
||||
(finalbufsize (rem ln buffersize)))
|
||||
;; Calculate the number of buffers we can process.
|
||||
;; if final buffer is not large enough for de-clipping we
|
||||
;; will just add it on the end as is.
|
||||
(if (>= finalbufsize slopelength)
|
||||
(setf buffercount (1+ (/ ln buffersize)))
|
||||
(setf buffercount (/ ln buffersize)))
|
||||
;;; Make output sequence from processed buffers
|
||||
(setf out
|
||||
(seqrep (i buffercount)
|
||||
(let* ((step (min buffersize (- ln (* i buffersize))))
|
||||
(buffer (snd-fetch-array sig step step))
|
||||
(processed (process buffer threshold step)))
|
||||
(cue (mult gain
|
||||
(snd-from-array 0 *sound-srate* processed))))))
|
||||
;;; If there's unprocessed audio remaining, add it to the end
|
||||
(if (and (> finalbufsize 0)(< finalbufsize slopelength))
|
||||
(seq out (cue (getfinalblock sig finalbufsize gain)))
|
||||
out)))
|
||||
|
||||
(setq exitlow (reverse exitlow))
|
||||
(setq returnlow (reverse returnlow))
|
||||
|
||||
(if (<= (aref r (1- drange)) threshlow)
|
||||
(setq returnlow (cdr returnlow)))
|
||||
(defun getfinalblock (sig step gain)
|
||||
(let ((block (snd-fetch-array sig step step)))
|
||||
(mult gain (snd-from-array 0 *sound-srate* block))))
|
||||
|
||||
(while (and exithigh returnhigh) ;;If there are more clipped regions
|
||||
(let* ((t1 (car exithigh)) ;;exit time
|
||||
(t2 (car returnhigh)) ;;return time
|
||||
(d1 (max 0 (/ (- (aref r t1) (aref r (- t1 (1- drange)))) (1- drange)))) ;;slope at exit
|
||||
(d2 (min 0 (/ (- (aref r (+ t2 (1- drange))) (aref r t2)) (1- drange)))) ;;slope at return
|
||||
(m (/ (+ d2 d1) (* (- t2 t1) (- t2 t1)))) ;;interpolation is by (t-t1)(t-t2)(mx+b)
|
||||
(b (- (/ d2 (- t2 t1)) (* m t2))) ;;These values of m and b make the cubic seamless
|
||||
(j (1+ t1))) ;; j is the index
|
||||
|
||||
(while (< j t2)
|
||||
(setf (aref r j) (+ (aref r t1) (* (- j t1) (- j t2) (+ (* m j) b))))
|
||||
(setf (aref r j) (+ (* (- t2 j) (/ (aref r t1) (- t2 t1))) (* (- j t1) (/ (aref r t2) (- t2 t1))) (* (- j t1) (- j t2) (+ (* m j) b))))
|
||||
(setq j (1+ j))))
|
||||
(setq exithigh (cdr exithigh))
|
||||
(setq returnhigh (cdr returnhigh)))
|
||||
(defun process (buffer threshold bufferlength)
|
||||
;;; Find threshold crossings
|
||||
(setf exit-list ()) ; list of times when waveform exceeds threshold
|
||||
(setf return-list ()) ; list of times when waveform returns below threshold
|
||||
;; Limitation of algorithm: the first and last 'slopelength' at ends of buffer are ignored
|
||||
;; so that we have enough samples beyond the threshold crossing to calculate the slope.
|
||||
(let ((last-sample (- bufferlength slopelength)))
|
||||
(do ((i slopelength (1+ i)))
|
||||
((>= i last-sample))
|
||||
(if (>= (abs (aref buffer i)) threshold)
|
||||
(when (< (abs (aref buffer (- i 1))) threshold) ; we just crossed threshold
|
||||
(push (- i 1) exit-list))
|
||||
(when (>= (abs (aref buffer (- i 1))) threshold) ; we just got back in range
|
||||
(push i return-list)))))
|
||||
;; Reverse lists back into chronological order.
|
||||
;; This is faster than appending values in chronological order.
|
||||
(setf exit-list (reverse exit-list))
|
||||
(setf return-list (reverse return-list))
|
||||
;; If the audio begins in a clipped region, discard the first return
|
||||
(when (>= (abs (aref buffer (1- slopelength))) threshold)
|
||||
(setq return-list (cdr return-list)))
|
||||
;; Interpolate between each pair of exit / entry points
|
||||
(let ((slopelen (1- slopelength)))
|
||||
(mapc (lambda (t0 t1)
|
||||
(interpolate buffer t0 t1 slopelen))
|
||||
exit-list return-list))
|
||||
buffer)
|
||||
|
||||
(while (and exitlow returnlow) ;;Same for bottom
|
||||
(let* ((t1 (car exitlow))
|
||||
(t2 (car returnlow))
|
||||
(d1 (min 0 (/ (- (aref r t1) (aref r (- t1 (1- drange)))) (1- drange)))) ;;slope at exit
|
||||
(d2 (max 0 (/ (- (aref r (+ t2 (1- drange))) (aref r t2)) (1- drange)))) ;;slope at return
|
||||
(m (/ (+ d2 d1) (* (- t2 t1) (- t2 t1))))
|
||||
(b (- (/ d2 (- t2 t1)) (* m t2)))
|
||||
(a (/ (+ (aref r t1) (aref r t2)) 2))
|
||||
(j (1+ t1)))
|
||||
(while (< j t2)
|
||||
(setf (aref r j) (+ (* (- t2 j) (/ (aref r t1) (- t2 t1))) (* (- j t1) (/ (aref r t2) (- t2 t1))) (* (- j t1) (- j t2) (+ (* m j) b))))
|
||||
(setq j (1+ j))))
|
||||
(setq exitlow (cdr exitlow))
|
||||
(setq returnlow (cdr returnlow)))
|
||||
|
||||
r)
|
||||
(defun interpolate (buffer t0 t1 dur)
|
||||
"Cubic spline interpolation"
|
||||
(let* ((d0 (/ (- (aref buffer t0) (aref buffer (- t0 dur))) dur)) ; slope at start
|
||||
(d1 (/ (- (aref buffer (+ t1 dur)) (aref buffer t1)) dur)) ; slope at end
|
||||
(m (/ (+ d1 d0) (* (- t1 t0) (- t1 t0))))
|
||||
(b (- (/ d1 (- t1 t0)) (* m t1))))
|
||||
(do ((j (1+ t0) (1+ j)))
|
||||
((= j t1))
|
||||
(setf (aref buffer j)
|
||||
(+ (* (- t1 j) (/ (aref buffer t0) (- t1 t0)))
|
||||
(* (- j t0) (/ (aref buffer t1) (- t1 t0)))
|
||||
(* (- j t0) (- j t1) (+ (* m j) b)))))))
|
||||
|
||||
(if (arrayp s)
|
||||
(dotimes (j (length s))
|
||||
(setf (aref s j) (declip (aref s j))))
|
||||
(setq s (declip s)))
|
||||
|
||||
s
|
||||
;; (get '*selection* 'peak) introduced in Audacity 2.1.3
|
||||
(multichan-expand #'declip *track* threshold (get '*selection* 'peak))
|
||||
|
@ -39,7 +39,7 @@ protected:
|
||||
// Make this protected to prevent slicing copies
|
||||
AudacityException( AudacityException&& ) {}
|
||||
AudacityException( const AudacityException& ) = default;
|
||||
AudacityException &operator = (AudacityException &&) {}
|
||||
AudacityException &operator = (AudacityException &&) { return *this;}
|
||||
AudacityException &operator = ( const AudacityException & ) PROHIBITED;
|
||||
};
|
||||
|
||||
|
@ -28,8 +28,8 @@
|
||||
To highlight this deliniation, the file is divided into three parts
|
||||
based on what thread context each function is intended to run in.
|
||||
|
||||
\par EXPERIMENTAL_MIDI_PLAYBACK
|
||||
If EXPERIMENTAL_MIDI_PLAYBACK is defined, this class also manages
|
||||
\par EXPERIMENTAL_MIDI_OUT
|
||||
If EXPERIMENTAL_MIDI_OUT is defined, this class also manages
|
||||
MIDI playback. The reason for putting MIDI here rather than in, say,
|
||||
class MidiIO, is that there is no high-level synchronization and
|
||||
transport architecture, so Audio and MIDI must be coupled in order
|
||||
@ -3790,7 +3790,7 @@ void AudioIO::OutputEvent()
|
||||
data1 = mNextEvent->get_pitch();
|
||||
if (mNextIsNoteOn) {
|
||||
data2 = mNextEvent->get_loud(); // get velocity
|
||||
int offset = mNextEventTrack->GetGain();
|
||||
int offset = mNextEventTrack->GetVelocity();
|
||||
data2 += offset; // offset comes from per-track slider
|
||||
// clip velocity to insure a legal note-on value
|
||||
data2 = (data2 < 0 ? 1 : (data2 > 127 ? 127 : data2));
|
||||
@ -3897,7 +3897,7 @@ void AudioIO::FillMidiBuffers()
|
||||
hasSolo = true;
|
||||
break;
|
||||
}
|
||||
int numMidiPlaybackTracks = gAudioIO->mMidiPlaybackTracks.size();
|
||||
auto numMidiPlaybackTracks = gAudioIO->mMidiPlaybackTracks.size();
|
||||
for(unsigned t = 0; t < numMidiPlaybackTracks; t++ )
|
||||
if( gAudioIO->mMidiPlaybackTracks[t]->GetSolo() ) {
|
||||
hasSolo = true;
|
||||
@ -4370,7 +4370,7 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
|
||||
if( gAudioIO->mPlaybackTracks[t]->GetSolo() )
|
||||
numSolo++;
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
int numMidiPlaybackTracks = gAudioIO->mMidiPlaybackTracks.size();
|
||||
auto numMidiPlaybackTracks = gAudioIO->mMidiPlaybackTracks.size();
|
||||
for( unsigned t = 0; t < numMidiPlaybackTracks; t++ )
|
||||
if( gAudioIO->mMidiPlaybackTracks[t]->GetSolo() )
|
||||
numSolo++;
|
||||
|
@ -135,7 +135,7 @@ void AutoRecoveryDialog::OnQuitAudacity(wxCommandEvent & WXUNUSED(event))
|
||||
void AutoRecoveryDialog::OnRecoverNone(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
int ret = wxMessageBox(
|
||||
_("Are you sure you want to discard all projects?\n\nChoosing \"Yes\" discards all projects immediately."),
|
||||
_("Are you sure you want to discard all recoverable projects?\n\nChoosing \"Yes\" discards all recoverable projects immediately."),
|
||||
_("Confirm Discard Projects"), wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT, this);
|
||||
|
||||
if (ret == wxYES)
|
||||
|
@ -278,7 +278,7 @@ BEGIN_EVENT_TABLE(DependencyDialog, wxDialogWrapper)
|
||||
EVT_LIST_ITEM_DESELECTED(FileListID, DependencyDialog::OnList)
|
||||
EVT_BUTTON(CopySelectedFilesButtonID, DependencyDialog::OnCopySelectedFiles)
|
||||
EVT_SIZE(DependencyDialog::OnSize)
|
||||
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) // mIsSaving ? "Cancel Save" : "Save without Copying"
|
||||
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) // mIsSaving ? "Cancel Save" : "Save Without Copying"
|
||||
EVT_BUTTON(wxID_YES, DependencyDialog::OnYes) // "Copy All Files (Safer)"
|
||||
EVT_BUTTON(wxID_CANCEL, DependencyDialog::OnCancel) // "Cancel Save"
|
||||
END_EVENT_TABLE()
|
||||
@ -349,7 +349,7 @@ void DependencyDialog::PopulateOrExchange(ShuttleGui& S)
|
||||
{
|
||||
if (mIsSaving) {
|
||||
S.Id(wxID_CANCEL).AddButton(_("Cancel Save"));
|
||||
S.Id(wxID_NO).AddButton(_("Save without Copying"));
|
||||
S.Id(wxID_NO).AddButton(_("Save Without Copying"));
|
||||
}
|
||||
else
|
||||
S.Id(wxID_NO).AddButton(_("Do Not Copy"));
|
||||
|
@ -198,7 +198,7 @@ EnvPoint *Envelope::AddPointAtEnd( double t, double val )
|
||||
|
||||
void Envelope::CopyFrom(const Envelope *e, double t0, double t1)
|
||||
{
|
||||
wxASSERT( t0 < t1 );
|
||||
wxASSERT( t0 <= t1 );
|
||||
|
||||
mOffset = wxMax(t0, e->mOffset);
|
||||
mTrackLen = wxMin(t1, e->mOffset + e->mTrackLen) - mOffset;
|
||||
|
@ -589,7 +589,7 @@ void LabelDialog::OnImport(wxCommandEvent & WXUNUSED(event))
|
||||
|
||||
// Ask user for a filename
|
||||
wxString fileName =
|
||||
FileSelector(_("Select a text file containing labels..."),
|
||||
FileSelector(_("Select a text file containing labels"),
|
||||
path, // Path
|
||||
wxT(""), // Name
|
||||
wxT(".txt"), // Extension
|
||||
|
@ -684,6 +684,17 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
|
||||
|
||||
c->AddSeparator();
|
||||
|
||||
c->AddSeparator();
|
||||
c->BeginSubMenu(_("S&kip to"));
|
||||
c->AddItem(wxT("SkipSelStart"), _("Selection Sta&rt"), FN(OnGoSelStart), wxT("Ctrl+["),
|
||||
TimeSelectedFlag, TimeSelectedFlag);
|
||||
c->AddItem(wxT("SkipSelEnd"), _("Selection En&d"), FN(OnGoSelEnd), wxT("Ctrl+]"),
|
||||
TimeSelectedFlag, TimeSelectedFlag);
|
||||
c->EndSubMenu();
|
||||
|
||||
c->AddSeparator();
|
||||
|
||||
c->AddCheck(wxT("ShowClipping"), _("&Show Clipping"), FN(OnShowClipping),
|
||||
gPrefs->Read(wxT("/GUI/ShowClipping"), 0L), AlwaysEnabledFlag, AlwaysEnabledFlag);
|
||||
|
||||
@ -784,17 +795,19 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
AudioIONotBusyFlag | CanStopAudioStreamFlag);
|
||||
/* i18n-hint: (verb)*/
|
||||
c->AddItem(wxT("Record"), _("&Record"), FN(OnRecord), wxT("R"));
|
||||
c->AddItem(wxT("TimerRecord"), _("&Timer Record..."), FN(OnTimerRecord), wxT("Shift+T"));
|
||||
|
||||
// The RecordBelow function is actually 'record-other', i.e. if normal record record beside,
|
||||
// it records below, if normal record records below, it records beside.
|
||||
// TODO: fix the naming, and also check we do 'the right thing' with other options like
|
||||
// TimerRecord.
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
c->AddItem(wxT("RecordBelow"), _("Record Below"), FN(OnRecordBelow), wxT("Shift+R"));
|
||||
// The RecordBelow function is actually 'record-other', i.e. if normal record records beside,
|
||||
// it records below, if normal record records below, it records beside.
|
||||
// TODO: fix the naming, and also check we do 'the right thing' with other options like
|
||||
// TimerRecord.
|
||||
// PREFER_NEW_TRACKS is defined if we want the old behaviour of by default adding a new track on
|
||||
// every new recording.
|
||||
#ifndef PREFER_NEW_TRACKS
|
||||
c->AddItem(wxT("RecordBelow"), _("Record New Track"), FN(OnRecordBelow), wxT("Shift+R"));
|
||||
#else
|
||||
c->AddItem(wxT("RecordBelow"), _("Record Beside"), FN(OnRecordBelow), wxT("Shift+R"));
|
||||
#endif
|
||||
|
||||
c->AddItem(wxT("TimerRecord"), _("&Timer Record..."), FN(OnTimerRecord), wxT("Shift+T"));
|
||||
// JKC: I decided to duplicate this between play and record, rather than put it
|
||||
// at the top level. AddItem can now cope with simple duplicated items.
|
||||
c->AddItem(wxT("Pause"), _("&Pause"), FN(OnPause), wxT("P"));
|
||||
@ -803,18 +816,6 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
// Scrubbing sub-menu
|
||||
GetScrubber().AddMenuItems();
|
||||
|
||||
c->AddSeparator();
|
||||
c->BeginSubMenu(_("Skip to"));
|
||||
c->AddItem(wxT("GoSelStart"), _("Selection Sta&rt"), FN(OnGoSelStart), wxT("Ctrl+["), TimeSelectedFlag, TimeSelectedFlag);
|
||||
c->AddItem(wxT("GoSelEnd"), _("Selection En&d"), FN(OnGoSelEnd), wxT("Ctrl+]"), TimeSelectedFlag, TimeSelectedFlag);
|
||||
|
||||
c->AddItem(wxT("SkipStart"), _("Track Start"), FN(OnSkipStart), wxT("Home"),
|
||||
AudioIONotBusyFlag, AudioIONotBusyFlag);
|
||||
c->AddItem(wxT("SkipEnd"), _("Track E&nd"), FN(OnSkipEnd), wxT("End"),
|
||||
WaveTracksExistFlag | AudioIONotBusyFlag,
|
||||
WaveTracksExistFlag | AudioIONotBusyFlag);
|
||||
c->EndSubMenu();
|
||||
|
||||
#ifndef EXPERIMENTAL_DA
|
||||
// JKC: ANSWER-ME: How is this different to 'Skip To' and how is it useful?
|
||||
c->BeginSubMenu(_("Cursor to"));
|
||||
@ -825,6 +826,9 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
c->AddItem(wxT("CursTrackStart"), _("Track &Start"), FN(OnCursorTrackStart), wxT("J"));
|
||||
c->AddItem(wxT("CursTrackEnd"), _("Track &End"), FN(OnCursorTrackEnd), wxT("K"));
|
||||
|
||||
c->AddItem(wxT("CursProjectStart"), _("&Project Start"), FN(OnSkipStart), wxT("Home"));
|
||||
c->AddItem(wxT("CursProjectEnd"), _("Project E&nd"), FN(OnSkipEnd), wxT("End"));
|
||||
|
||||
c->EndSubMenu();
|
||||
#endif
|
||||
|
||||
@ -4604,11 +4608,13 @@ bool AudacityProject::HandlePasteNothingSelected()
|
||||
pNewTrack = mTrackFactory->NewWaveTrack(w->GetSampleFormat(), w->GetRate());
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef USE_MIDI
|
||||
case Track::Note:
|
||||
pNewTrack = mTrackFactory->NewNoteTrack();
|
||||
break;
|
||||
#endif // USE_MIDI
|
||||
case Track::Note:
|
||||
pNewTrack = mTrackFactory->NewNoteTrack();
|
||||
break;
|
||||
#endif // USE_MIDI
|
||||
|
||||
case Track::Label:
|
||||
pNewTrack = mTrackFactory->NewLabelTrack();
|
||||
break;
|
||||
@ -5807,7 +5813,7 @@ void AudacityProject::OnImportLabels()
|
||||
wxString path = gPrefs->Read(wxT("/DefaultOpenPath"),::wxGetCwd());
|
||||
|
||||
wxString fileName =
|
||||
FileSelector(_("Select a text file containing labels..."),
|
||||
FileSelector(_("Select a text file containing labels"),
|
||||
path, // Path
|
||||
wxT(""), // Name
|
||||
wxT(".txt"), // Extension
|
||||
@ -5852,7 +5858,7 @@ void AudacityProject::OnImportMIDI()
|
||||
{
|
||||
wxString path = gPrefs->Read(wxT("/DefaultOpenPath"),::wxGetCwd());
|
||||
|
||||
wxString fileName = FileSelector(_("Select a MIDI file..."),
|
||||
wxString fileName = FileSelector(_("Select a MIDI file"),
|
||||
path, // Path
|
||||
wxT(""), // Name
|
||||
wxT(""), // Extension
|
||||
@ -5903,7 +5909,7 @@ void AudacityProject::OnImportRaw()
|
||||
wxString path = gPrefs->Read(wxT("/DefaultOpenPath"),::wxGetCwd());
|
||||
|
||||
wxString fileName =
|
||||
FileSelector(_("Select any uncompressed audio file..."),
|
||||
FileSelector(_("Select any uncompressed audio file"),
|
||||
path, // Path
|
||||
wxT(""), // Name
|
||||
wxT(""), // Extension
|
||||
@ -6146,12 +6152,7 @@ void AudacityProject::HandleAlign(int index, bool moveSel)
|
||||
|
||||
while (t) {
|
||||
// We only want Wave and Note tracks here.
|
||||
#if defined(USE_MIDI)
|
||||
if (t->GetSelected() && ((t->GetKind() == Track::Wave) ||
|
||||
(t->GetKind() == Track::Note)))
|
||||
#else
|
||||
if (t->GetSelected() && (t->GetKind() == Track::Wave))
|
||||
#endif
|
||||
if (t->GetSelected() && dynamic_cast<const AudioTrack*>(t))
|
||||
{
|
||||
offset = t->GetOffset();
|
||||
if (t->GetLinked()) { // Left channel of stereo track.
|
||||
@ -6232,12 +6233,7 @@ void AudacityProject::HandleAlign(int index, bool moveSel)
|
||||
while (t) {
|
||||
// This shifts different tracks in different ways, so no sync-lock move.
|
||||
// Only align Wave and Note tracks end to end.
|
||||
#if defined(USE_MIDI)
|
||||
if (t->GetSelected() && ((t->GetKind() == Track::Wave) ||
|
||||
(t->GetKind() == Track::Note)))
|
||||
#else
|
||||
if (t->GetSelected() && (t->GetKind() == Track::Wave))
|
||||
#endif
|
||||
if (t->GetSelected() && dynamic_cast<const AudioTrack*>(t))
|
||||
{
|
||||
t->SetOffset(newPos); // Move the track
|
||||
|
||||
@ -6523,7 +6519,7 @@ void AudacityProject::OnScoreAlign()
|
||||
if (alignedNoteTrack->GetSequence() == NULL) {
|
||||
holder = alignedNoteTrack->Duplicate();
|
||||
alignedNoteTrack = static_cast<NoteTrack*>(holder.get());
|
||||
assert(alignedNoteTrack->GetSequence());
|
||||
wxASSERT(alignedNoteTrack->GetSequence());
|
||||
}
|
||||
// Remove offset from NoteTrack because audio is
|
||||
// mixed starting at zero and incorporating clip offsets.
|
||||
@ -6893,8 +6889,9 @@ void AudacityProject::OnRemoveTracks()
|
||||
|
||||
while (t) {
|
||||
if (t->GetSelected()) {
|
||||
if (mMixerBoard && (t->GetKind() == Track::Wave))
|
||||
mMixerBoard->RemoveTrackCluster((WaveTrack*)t);
|
||||
auto playable = dynamic_cast<PlayableTrack*>(t);
|
||||
if (mMixerBoard && playable)
|
||||
mMixerBoard->RemoveTrackCluster(playable);
|
||||
if (!f)
|
||||
f = l; // Capture the track preceeding the first removed track
|
||||
t = iter.RemoveCurrent();
|
||||
@ -7091,8 +7088,9 @@ void AudacityProject::OnMuteAllTracks()
|
||||
|
||||
while (t)
|
||||
{
|
||||
if (t->GetKind() == Track::Wave)
|
||||
t->SetMute(true);
|
||||
auto pt = dynamic_cast<PlayableTrack *>(t);
|
||||
if (pt)
|
||||
pt->SetMute(true);
|
||||
|
||||
t = iter.Next();
|
||||
}
|
||||
@ -7110,7 +7108,9 @@ void AudacityProject::OnUnMuteAllTracks()
|
||||
|
||||
while (t)
|
||||
{
|
||||
t->SetMute(false);
|
||||
auto pt = dynamic_cast<PlayableTrack *>(t);
|
||||
if (pt)
|
||||
pt->SetMute(false);
|
||||
t = iter.Next();
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
|
||||
, mQueueMaxLen{ 65536 }
|
||||
, mSampleQueue{ mNumInputTracks, mQueueMaxLen }
|
||||
|
||||
, mNumChannels{ static_cast<size_t>(numOutChannels) }
|
||||
, mNumChannels{ numOutChannels }
|
||||
, mGains{ mNumChannels }
|
||||
|
||||
, mMayThrow{ mayThrow }
|
||||
|
@ -23,9 +23,9 @@
|
||||
|
||||
#include "AColor.h"
|
||||
#include "AudioIO.h"
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
#include "NoteTrack.h"
|
||||
#endif
|
||||
|
||||
#include "NoteTrack.h"
|
||||
|
||||
#include "Project.h"
|
||||
#include "TrackPanel.h" // for EVT_TRACK_PANEL_TIMER
|
||||
#include "UndoManager.h"
|
||||
@ -155,30 +155,17 @@ END_EVENT_TABLE()
|
||||
|
||||
MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
|
||||
MixerBoard* grandParent, AudacityProject* project,
|
||||
WaveTrack* pLeftTrack, WaveTrack* pRightTrack /*= NULL*/,
|
||||
PlayableTrack* pTrack,
|
||||
const wxPoint& pos /*= wxDefaultPosition*/,
|
||||
const wxSize& size /*= wxDefaultSize*/)
|
||||
: wxPanelWrapper(parent, -1, pos, size)
|
||||
, mTrack{ pTrack }
|
||||
{
|
||||
mMixerBoard = grandParent;
|
||||
mProject = project;
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (pLeftTrack->GetKind() == Track::Note) {
|
||||
mLeftTrack = NULL;
|
||||
mNoteTrack = (NoteTrack*) pLeftTrack;
|
||||
mTrack = pLeftTrack;
|
||||
} else {
|
||||
wxASSERT(pLeftTrack->GetKind() == Track::Wave);
|
||||
mTrack = mLeftTrack = pLeftTrack;
|
||||
mNoteTrack = NULL;
|
||||
}
|
||||
#else
|
||||
wxASSERT(pLeftTrack->GetKind() == Track::Wave);
|
||||
mLeftTrack = pLeftTrack;
|
||||
#endif
|
||||
mRightTrack = pRightTrack;
|
||||
wxASSERT( pTrack );
|
||||
|
||||
SetName(mLeftTrack->GetName());
|
||||
SetName(mTrack->GetName());
|
||||
|
||||
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
|
||||
|
||||
@ -191,13 +178,8 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
|
||||
wxPoint ctrlPos(kDoubleInset, kDoubleInset);
|
||||
wxSize ctrlSize(size.GetWidth() - kQuadrupleInset, TRACK_NAME_HEIGHT);
|
||||
mStaticText_TrackName =
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
safenew wxStaticText(this, -1, mTrack->GetName(), ctrlPos, ctrlSize,
|
||||
wxALIGN_CENTRE | wxST_NO_AUTORESIZE | wxSUNKEN_BORDER);
|
||||
#else
|
||||
safenew wxStaticText(this, -1, mLeftTrack->GetName(), ctrlPos, ctrlSize,
|
||||
wxALIGN_CENTRE | 0x0001 | wxBORDER_SUNKEN);
|
||||
#endif
|
||||
//v Useful when different tracks are different colors, but not now.
|
||||
// mStaticText_TrackName->SetBackgroundColour(this->GetTrackColor());
|
||||
|
||||
@ -208,8 +190,9 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
|
||||
const int nGainSliderHeight =
|
||||
size.GetHeight() - ctrlPos.y - kQuadrupleInset;
|
||||
ctrlSize.Set(kLeftSideStackWidth - kQuadrupleInset, nGainSliderHeight);
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (mNoteTrack) {
|
||||
|
||||
#ifdef USE_MIDI
|
||||
if (GetNote()) {
|
||||
mSlider_Gain =
|
||||
safenew MixerTrackSlider(
|
||||
this, ID_SLIDER_GAIN,
|
||||
@ -217,15 +200,17 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
|
||||
_("Velocity"),
|
||||
ctrlPos, ctrlSize, VEL_SLIDER, true,
|
||||
true, 0.0, wxVERTICAL);
|
||||
} else
|
||||
}
|
||||
else
|
||||
#endif
|
||||
mSlider_Gain =
|
||||
safenew MixerTrackSlider(
|
||||
this, ID_SLIDER_GAIN,
|
||||
/* i18n-hint: title of the Gain slider, used to adjust the volume */
|
||||
_("Gain"),
|
||||
ctrlPos, ctrlSize, DB_SLIDER, true,
|
||||
true, 0.0, wxVERTICAL);
|
||||
mSlider_Gain =
|
||||
safenew MixerTrackSlider(
|
||||
this, ID_SLIDER_GAIN,
|
||||
/* i18n-hint: title of the Gain slider, used to adjust the volume */
|
||||
_("Gain"),
|
||||
ctrlPos, ctrlSize, DB_SLIDER, true,
|
||||
true, 0.0, wxVERTICAL);
|
||||
|
||||
mSlider_Gain->SetName(_("Gain"));
|
||||
|
||||
this->UpdateGain();
|
||||
@ -236,11 +221,7 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
|
||||
// musical instrument image
|
||||
ctrlPos.x += kLeftSideStackWidth + kInset; // + kInset to center it in right side stack
|
||||
ctrlSize.Set(MUSICAL_INSTRUMENT_HEIGHT_AND_WIDTH, MUSICAL_INSTRUMENT_HEIGHT_AND_WIDTH);
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mTrack->GetName());
|
||||
#else
|
||||
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mLeftTrack);
|
||||
#endif
|
||||
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mTrack);
|
||||
wxASSERT(bitmap);
|
||||
mBitmapButton_MusicalInstrument =
|
||||
safenew wxBitmapButton(this, ID_BITMAPBUTTON_MUSICAL_INSTRUMENT, *bitmap,
|
||||
@ -306,34 +287,24 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
|
||||
(PAN_HEIGHT + kDoubleInset) -
|
||||
(MUTE_SOLO_HEIGHT + (bSoloNone ? 0 : MUTE_SOLO_HEIGHT) + kDoubleInset);
|
||||
ctrlSize.Set(kRightSideStackWidth, nMeterHeight);
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (mLeftTrack) {
|
||||
#endif
|
||||
mMeter =
|
||||
safenew Meter(GetActiveProject(), // AudacityProject* project,
|
||||
this, -1, // wxWindow* parent, wxWindowID id,
|
||||
false, // bool isInput
|
||||
ctrlPos, ctrlSize, // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
Meter::MixerTrackCluster); // Style style = HorizontalStereo,
|
||||
mMeter->SetName(_("Signal Level Meter"));
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
} else {
|
||||
mMeter = NULL;
|
||||
|
||||
mMeter = NULL;
|
||||
if (GetWave()) {
|
||||
mMeter =
|
||||
safenew Meter(GetActiveProject(), // AudacityProject* project,
|
||||
this, -1, // wxWindow* parent, wxWindowID id,
|
||||
false, // bool isInput
|
||||
ctrlPos, ctrlSize, // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
Meter::MixerTrackCluster); // Style style = HorizontalStereo,
|
||||
mMeter->SetName(_("Signal Level Meter"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if wxUSE_TOOLTIPS
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mStaticText_TrackName->SetToolTip(mTrack->GetName());
|
||||
#else
|
||||
mStaticText_TrackName->SetToolTip(mLeftTrack->GetName());
|
||||
#endif
|
||||
mToggleButton_Mute->SetToolTip(_("Mute"));
|
||||
mToggleButton_Solo->SetToolTip(_("Solo"));
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (mLeftTrack)
|
||||
#endif
|
||||
mMeter->SetToolTip(_("Signal Level Meter"));
|
||||
if (GetWave())
|
||||
mMeter->SetToolTip(_("Signal Level Meter"));
|
||||
#endif // wxUSE_TOOLTIPS
|
||||
|
||||
#ifdef __WXMAC__
|
||||
@ -344,9 +315,31 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
|
||||
#endif
|
||||
}
|
||||
|
||||
WaveTrack *MixerTrackCluster::GetWave() const
|
||||
{
|
||||
return dynamic_cast< WaveTrack * >( mTrack );
|
||||
}
|
||||
|
||||
WaveTrack *MixerTrackCluster::GetRight() const
|
||||
{
|
||||
auto left = GetWave();
|
||||
if (left)
|
||||
return static_cast<WaveTrack*>(left->GetLink());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef USE_MIDI
|
||||
NoteTrack *MixerTrackCluster::GetNote() const
|
||||
{
|
||||
return dynamic_cast< NoteTrack * >( mTrack );
|
||||
}
|
||||
#endif
|
||||
|
||||
void MixerTrackCluster::UpdatePrefs()
|
||||
{
|
||||
mMeter->UpdatePrefs(); // in case meter range has changed
|
||||
if (mMeter)
|
||||
mMeter->UpdatePrefs(); // in case meter range has changed
|
||||
HandleResize(); // in case prefs "/GUI/Solo" changed
|
||||
}
|
||||
|
||||
@ -382,30 +375,24 @@ void MixerTrackCluster::HandleResize() // For wxSizeEvents, update gain slider a
|
||||
TRACK_NAME_HEIGHT + kDoubleInset +
|
||||
nRequiredHeightAboveMeter;
|
||||
const int nMeterHeight = nGainSliderHeight - nRequiredHeightAboveMeter;
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (mMeter)
|
||||
#endif
|
||||
mMeter->SetSize(-1, nMeterY, -1, nMeterHeight);
|
||||
mMeter->SetSize(-1, nMeterY, -1, nMeterHeight);
|
||||
}
|
||||
|
||||
void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/)
|
||||
{
|
||||
float fValue = mSlider_Gain->Get();
|
||||
if (mLeftTrack)
|
||||
mLeftTrack->SetGain(fValue);
|
||||
if (GetWave())
|
||||
GetWave()->SetGain(fValue);
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
else
|
||||
mNoteTrack->SetGain(fValue);
|
||||
GetNote()->SetVelocity(fValue);
|
||||
#endif
|
||||
if (mRightTrack)
|
||||
mRightTrack->SetGain(fValue);
|
||||
if (GetRight())
|
||||
GetRight()->SetGain(fValue);
|
||||
|
||||
// Update the TrackPanel correspondingly.
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mProject->RefreshTPTrack(mTrack);
|
||||
#else
|
||||
mProject->RefreshTPTrack(mLeftTrack);
|
||||
#endif
|
||||
if (bWantPushState)
|
||||
mProject->TP_PushState(_("Moved gain slider"), _("Gain"), UndoPush::CONSOLIDATE );
|
||||
}
|
||||
@ -413,17 +400,13 @@ void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/)
|
||||
void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/)
|
||||
{
|
||||
float fValue = mSlider_Pan->Get();
|
||||
if (mLeftTrack) // test in case track is a NoteTrack
|
||||
mLeftTrack->SetPan(fValue);
|
||||
if (mRightTrack)
|
||||
mRightTrack->SetPan(fValue);
|
||||
if (GetWave()) // test in case track is a NoteTrack
|
||||
GetWave()->SetPan(fValue);
|
||||
if (GetRight())
|
||||
GetRight()->SetPan(fValue);
|
||||
|
||||
// Update the TrackPanel correspondingly.
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mProject->RefreshTPTrack(mTrack);
|
||||
#else
|
||||
mProject->RefreshTPTrack(mLeftTrack);
|
||||
#endif
|
||||
|
||||
if (bWantPushState)
|
||||
mProject->TP_PushState(_("Moved pan slider"), _("Pan"), UndoPush::CONSOLIDATE );
|
||||
@ -431,10 +414,8 @@ void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/)
|
||||
|
||||
void MixerTrackCluster::ResetMeter(const bool bResetClipping)
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (mMeter)
|
||||
#endif
|
||||
mMeter->Reset(mLeftTrack->GetRate(), bResetClipping);
|
||||
mMeter->Reset(GetWave()->GetRate(), bResetClipping);
|
||||
}
|
||||
|
||||
|
||||
@ -450,33 +431,20 @@ void MixerTrackCluster::UpdateForStateChange()
|
||||
|
||||
void MixerTrackCluster::UpdateName()
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
const wxString newName = mTrack->GetName();
|
||||
#else
|
||||
const wxString newName = mLeftTrack->GetName();
|
||||
#endif
|
||||
SetName(newName);
|
||||
mStaticText_TrackName->SetLabel(newName);
|
||||
#if wxUSE_TOOLTIPS
|
||||
mStaticText_TrackName->SetToolTip(newName);
|
||||
#endif
|
||||
mBitmapButton_MusicalInstrument->SetBitmapLabel(
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
*(mMixerBoard->GetMusicalInstrumentBitmap(newName)));
|
||||
#else
|
||||
*(mMixerBoard->GetMusicalInstrumentBitmap(mLeftTrack)));
|
||||
#endif
|
||||
*(mMixerBoard->GetMusicalInstrumentBitmap(mTrack)));
|
||||
}
|
||||
|
||||
void MixerTrackCluster::UpdateMute()
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0);
|
||||
if (mTrack->GetMute())
|
||||
#else
|
||||
mToggleButton_Mute->SetAlternateIdx(mLeftTrack->GetSolo() ? 1 : 0);
|
||||
if (mLeftTrack->GetMute())
|
||||
#endif
|
||||
mToggleButton_Mute->PushDown();
|
||||
else
|
||||
mToggleButton_Mute->PopUp();
|
||||
@ -484,11 +452,7 @@ void MixerTrackCluster::UpdateMute()
|
||||
|
||||
void MixerTrackCluster::UpdateSolo()
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
bool bIsSolo = mTrack->GetSolo();
|
||||
#else
|
||||
bool bIsSolo = mLeftTrack->GetSolo();
|
||||
#endif
|
||||
if (bIsSolo)
|
||||
mToggleButton_Solo->PushDown();
|
||||
else
|
||||
@ -499,55 +463,36 @@ void MixerTrackCluster::UpdateSolo()
|
||||
void MixerTrackCluster::UpdatePan()
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (mNoteTrack) {
|
||||
if (!GetWave()) {
|
||||
mSlider_Pan->Hide();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
mSlider_Pan->Set(mLeftTrack->GetPan());
|
||||
mSlider_Pan->Set(GetWave()->GetPan());
|
||||
}
|
||||
|
||||
void MixerTrackCluster::UpdateGain()
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (mNoteTrack) {
|
||||
if (!GetWave()) {
|
||||
mSlider_Gain->SetStyle(VEL_SLIDER);
|
||||
mSlider_Gain->Set(mNoteTrack->GetGain());
|
||||
mSlider_Gain->Set(GetNote()->GetVelocity());
|
||||
return;
|
||||
}
|
||||
mSlider_Gain->SetStyle(DB_SLIDER);
|
||||
#endif
|
||||
mSlider_Gain->Set(mLeftTrack->GetGain());
|
||||
mSlider_Gain->Set(GetWave()->GetGain());
|
||||
}
|
||||
|
||||
void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
// NoteTracks do not (currently) register on meters. It would probably be
|
||||
// a good idea to display 16 channel "active" lights rather than a meter
|
||||
if (!mLeftTrack)
|
||||
if (!GetWave())
|
||||
return;
|
||||
#else
|
||||
wxASSERT(mLeftTrack && (mLeftTrack->GetKind() == Track::Wave));
|
||||
#endif
|
||||
|
||||
//vvv Vaughan, 2010-11-27:
|
||||
// NOTE TO ROGER DANNENBERG:
|
||||
// I undid the mTrack hack in this conditional, as the rest of the method still assumed it's a wavetrack
|
||||
// so dereferencing mLeftTrack would have gotten a NULL pointer fault.
|
||||
// I really think MixerTrackCluster should be factored for NoteTracks.
|
||||
// REPLY: I think bSuccess prevents dereferencing mLeftTrack, but I will
|
||||
// check. We should talk about whether it's better to factor
|
||||
// MixerTrackCluster or more fully hide track types from MixerTrackCluster.
|
||||
// For now, out change plan produced the following:
|
||||
// Vaughan, 2011=10-15: There's no bSuccess here, so I don't know what you mean.
|
||||
// But this change is consistent with the others for EXPERIMENTAL_MIDI_OUT, so I accept it.
|
||||
if ((t0 < 0.0) || (t1 < 0.0) || (t0 >= t1) || // bad time value or nothing to show
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
((mMixerBoard->HasSolo() || mTrack->GetMute()) && !mTrack->GetSolo())
|
||||
#else
|
||||
((mMixerBoard->HasSolo() || mLeftTrack->GetMute()) && !mLeftTrack->GetSolo())
|
||||
#endif
|
||||
)
|
||||
{
|
||||
//v Vaughan, 2011-02-25: Moved the update back to TrackPanel::OnTimer() as it helps with
|
||||
@ -577,7 +522,7 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
//Floats rmsRight{kFramesPerBuffer};
|
||||
//
|
||||
//#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
// bool bSuccess = (mLeftTrack != NULL);
|
||||
// bool bSuccess = (GetWave() != nullptr);
|
||||
//#else
|
||||
// bool bSuccess = true;
|
||||
//#endif
|
||||
@ -589,8 +534,8 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
//while (bSuccess && (i < kFramesPerBuffer))
|
||||
//{
|
||||
// bSuccess &=
|
||||
// mLeftTrack->GetMinMax(&min, &(maxLeft[i]), dFrameT0, dFrameT1) &&
|
||||
// mLeftTrack->GetRMS(&(rmsLeft[i]), dFrameT0, dFrameT1);
|
||||
// mTrack->GetMinMax(&min, &(maxLeft[i]), dFrameT0, dFrameT1) &&
|
||||
// mTrack->GetRMS(&(rmsLeft[i]), dFrameT0, dFrameT1);
|
||||
// if (bSuccess && mRightTrack)
|
||||
// bSuccess &=
|
||||
// mRightTrack->GetMinMax(&min, &(maxRight[i]), dFrameT0, dFrameT1) &&
|
||||
@ -613,7 +558,7 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
//{
|
||||
// for (i = 0; i < kFramesPerBuffer; i++)
|
||||
// {
|
||||
// float gain = mLeftTrack->GetChannelGain(0);
|
||||
// float gain = mTrack->GetChannelGain(0);
|
||||
// maxLeft[i] *= gain;
|
||||
// rmsLeft[i] *= gain;
|
||||
// if (mRightTrack)
|
||||
@ -621,17 +566,18 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
// maxRight[i] *= gain;
|
||||
// rmsRight[i] *= gain;
|
||||
// }
|
||||
// mMeter->UpdateDisplay(
|
||||
// if ( mMeter ) mMeter->UpdateDisplay(
|
||||
// 2, // If mono, show left track values in both meters, as in MeterToolBar, rather than kNumChannels.
|
||||
// kFramesPerBuffer,
|
||||
// maxLeft, rmsLeft,
|
||||
// maxRight, rmsRight,
|
||||
// mLeftTrack->TimeToLongSamples(t1 - t0));
|
||||
// mTrack->TimeToLongSamples(t1 - t0));
|
||||
//}
|
||||
//
|
||||
|
||||
auto startSample = (sampleCount)((mLeftTrack->GetRate() * t0) + 0.5);
|
||||
auto scnFrames = (sampleCount)((mLeftTrack->GetRate() * (t1 - t0)) + 0.5);
|
||||
const auto pTrack = GetWave();
|
||||
auto startSample = (sampleCount)((pTrack->GetRate() * t0) + 0.5);
|
||||
auto scnFrames = (sampleCount)((pTrack->GetRate() * (t1 - t0)) + 0.5);
|
||||
|
||||
// Expect that the difference of t1 and t0 is the part of a track played
|
||||
// in about 1/20 second (ticks of TrackPanel timer), so this won't overflow
|
||||
@ -640,7 +586,7 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
Floats tempFloatsArray{ nFrames };
|
||||
decltype(tempFloatsArray) meterFloatsArray;
|
||||
// Don't throw on read error in this drawing update routine
|
||||
bool bSuccess = mLeftTrack->Get((samplePtr)tempFloatsArray.get(),
|
||||
bool bSuccess = pTrack->Get((samplePtr)tempFloatsArray.get(),
|
||||
floatSample, startSample, nFrames, fillZero, false);
|
||||
if (bSuccess)
|
||||
{
|
||||
@ -653,9 +599,9 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
for (int index = 0; index < nFrames; index++)
|
||||
meterFloatsArray[2 * index] = tempFloatsArray[index];
|
||||
|
||||
if (mRightTrack)
|
||||
if (GetRight())
|
||||
// Again, don't throw
|
||||
bSuccess = mRightTrack->Get((samplePtr)tempFloatsArray.get(),
|
||||
bSuccess = GetRight()->Get((samplePtr)tempFloatsArray.get(),
|
||||
floatSample, startSample, nFrames, fillZero, false);
|
||||
|
||||
if (bSuccess)
|
||||
@ -669,14 +615,14 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
if (bSuccess)
|
||||
{
|
||||
//vvv Need to apply envelope, too? See Mixer::MixSameRate.
|
||||
float gain = mLeftTrack->GetChannelGain(0);
|
||||
float gain = pTrack->GetChannelGain(0);
|
||||
if (gain < 1.0)
|
||||
for (int index = 0; index < nFrames; index++)
|
||||
meterFloatsArray[2 * index] *= gain;
|
||||
if (mRightTrack)
|
||||
gain = mRightTrack->GetChannelGain(1);
|
||||
if (GetRight())
|
||||
gain = GetRight()->GetChannelGain(1);
|
||||
else
|
||||
gain = mLeftTrack->GetChannelGain(1);
|
||||
gain = pTrack->GetChannelGain(1);
|
||||
if (gain < 1.0)
|
||||
for (int index = 0; index < nFrames; index++)
|
||||
meterFloatsArray[(2 * index) + 1] *= gain;
|
||||
@ -705,13 +651,7 @@ wxColour MixerTrackCluster::GetTrackColor()
|
||||
|
||||
void MixerTrackCluster::HandleSelect(bool bShiftDown, bool bControlDown)
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
Track *pTrack = mTrack;
|
||||
#else
|
||||
Track *pTrack = mLeftTrack;
|
||||
#endif
|
||||
|
||||
mProject->GetTrackPanel()->HandleListSelection(pTrack, bShiftDown, bControlDown);
|
||||
mProject->GetTrackPanel()->HandleListSelection(mTrack, bShiftDown, bControlDown);
|
||||
}
|
||||
|
||||
void MixerTrackCluster::OnMouseEvent(wxMouseEvent& event)
|
||||
@ -735,11 +675,7 @@ void MixerTrackCluster::OnPaint(wxPaintEvent & WXUNUSED(event))
|
||||
wxSize clusterSize = this->GetSize();
|
||||
wxRect bev(0, 0, clusterSize.GetWidth() - 1, clusterSize.GetHeight() - 1);
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
auto selected = mTrack->GetSelected();
|
||||
#else
|
||||
auto selected = mLeftTrack->GetSelected();
|
||||
#endif
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++) // 4 gives a big bevel, but there were complaints about visibility otherwise.
|
||||
{
|
||||
@ -782,13 +718,8 @@ void MixerTrackCluster::OnSlider_Pan(wxCommandEvent& WXUNUSED(event))
|
||||
|
||||
void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mProject->HandleTrackMute(mTrack, mToggleButton_Mute->WasShiftDown());
|
||||
mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0);
|
||||
#else
|
||||
mProject->HandleTrackMute(mLeftTrack, mToggleButton_Mute->WasShiftDown());
|
||||
mToggleButton_Mute->SetAlternateIdx(mLeftTrack->GetSolo() ? 1 : 0);
|
||||
#endif
|
||||
|
||||
// Update the TrackPanel correspondingly.
|
||||
if (mProject->IsSoloSimple())
|
||||
@ -799,22 +730,13 @@ void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
|
||||
}
|
||||
else
|
||||
// Update only the changed track.
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mProject->RefreshTPTrack(mTrack);
|
||||
#else
|
||||
mProject->RefreshTPTrack(mLeftTrack);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mProject->HandleTrackSolo(mTrack, mToggleButton_Solo->WasShiftDown());
|
||||
bool bIsSolo = mTrack->GetSolo();
|
||||
#else
|
||||
mProject->HandleTrackSolo(mLeftTrack, mToggleButton_Solo->WasShiftDown());
|
||||
bool bIsSolo = mLeftTrack->GetSolo();
|
||||
#endif
|
||||
mToggleButton_Mute->SetAlternateIdx(bIsSolo ? 1 : 0);
|
||||
|
||||
// Update the TrackPanel correspondingly.
|
||||
@ -827,11 +749,7 @@ void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
|
||||
}
|
||||
else
|
||||
// Update only the changed track.
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mProject->RefreshTPTrack(mTrack);
|
||||
#else
|
||||
mProject->RefreshTPTrack(mLeftTrack);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1006,22 +924,18 @@ void MixerBoard::UpdateTrackClusters()
|
||||
this->CreateMuteSoloImages();
|
||||
|
||||
const int nClusterHeight = mScrolledWindow->GetClientSize().GetHeight() - kDoubleInset;
|
||||
const size_t nClusterCount = mMixerTrackClusters.GetCount();
|
||||
size_t nClusterCount = mMixerTrackClusters.GetCount();
|
||||
unsigned int nClusterIndex = 0;
|
||||
TrackListIterator iterTracks(mTracks);
|
||||
MixerTrackCluster* pMixerTrackCluster = NULL;
|
||||
Track* pLeftTrack;
|
||||
Track* pTrack;
|
||||
Track* pRightTrack;
|
||||
|
||||
pLeftTrack = iterTracks.First();
|
||||
while (pLeftTrack) {
|
||||
pRightTrack = pLeftTrack->GetLinked() ? iterTracks.Next() : NULL;
|
||||
pTrack = iterTracks.First();
|
||||
while (pTrack) {
|
||||
pRightTrack = pTrack->GetLinked() ? iterTracks.Next() : NULL;
|
||||
|
||||
if (pLeftTrack->GetKind() == Track::Wave
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
|| pLeftTrack->GetKind() == Track::Note
|
||||
#endif
|
||||
)
|
||||
if (auto pPlayableTrack = dynamic_cast<PlayableTrack*>(pTrack))
|
||||
{
|
||||
if (nClusterIndex < nClusterCount)
|
||||
{
|
||||
@ -1029,20 +943,8 @@ void MixerBoard::UpdateTrackClusters()
|
||||
// Track clusters are maintained in the same order as the WaveTracks.
|
||||
// Track pointers can change for the "same" track for different states
|
||||
// on the undo stack, so update the pointers and display name.
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (pLeftTrack->GetKind() == Track::Note) {
|
||||
mMixerTrackClusters[nClusterIndex]->mNoteTrack = (NoteTrack*)pLeftTrack;
|
||||
mMixerTrackClusters[nClusterIndex]->mLeftTrack = NULL;
|
||||
} else {
|
||||
mMixerTrackClusters[nClusterIndex]->mNoteTrack = NULL;
|
||||
mMixerTrackClusters[nClusterIndex]->mLeftTrack = (WaveTrack*)pLeftTrack;
|
||||
}
|
||||
#else
|
||||
mMixerTrackClusters[nClusterIndex]->mLeftTrack = (WaveTrack*)pLeftTrack;
|
||||
#endif
|
||||
mMixerTrackClusters[nClusterIndex]->mTrack = pPlayableTrack;
|
||||
// Assume linked track is wave or null
|
||||
mMixerTrackClusters[nClusterIndex]->mRightTrack =
|
||||
static_cast<WaveTrack*>(pRightTrack);
|
||||
mMixerTrackClusters[nClusterIndex]->UpdateForStateChange();
|
||||
}
|
||||
else
|
||||
@ -1057,16 +959,14 @@ void MixerBoard::UpdateTrackClusters()
|
||||
wxSize clusterSize(kMixerTrackClusterWidth, nClusterHeight);
|
||||
pMixerTrackCluster =
|
||||
safenew MixerTrackCluster(mScrolledWindow, this, mProject,
|
||||
static_cast<WaveTrack*>(pLeftTrack),
|
||||
// Assume linked track is wave or null
|
||||
static_cast<WaveTrack*>(pRightTrack),
|
||||
pPlayableTrack,
|
||||
clusterPos, clusterSize);
|
||||
if (pMixerTrackCluster)
|
||||
mMixerTrackClusters.Add(pMixerTrackCluster);
|
||||
}
|
||||
nClusterIndex++;
|
||||
}
|
||||
pLeftTrack = iterTracks.Next();
|
||||
pTrack = iterTracks.Next();
|
||||
}
|
||||
|
||||
if (pMixerTrackCluster)
|
||||
@ -1075,19 +975,14 @@ void MixerBoard::UpdateTrackClusters()
|
||||
this->UpdateWidth();
|
||||
this->ResizeTrackClusters();
|
||||
}
|
||||
else if (nClusterIndex < nClusterCount)
|
||||
else while (nClusterIndex < nClusterCount)
|
||||
{
|
||||
// We've got too many clusters.
|
||||
// This can happen only on things like Undo New Audio Track or Undo Import
|
||||
// that don't call RemoveTrackCluster explicitly.
|
||||
// We've already updated the track pointers for the clusters to the left, so just remove all the rest.
|
||||
// Keep nClusterIndex constant and successively DELETE from left to right.
|
||||
for (unsigned int nCounter = nClusterIndex; nCounter < nClusterCount; nCounter++)
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mTrack);
|
||||
#else
|
||||
this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mLeftTrack);
|
||||
#endif
|
||||
// Successively DELETE from right to left.
|
||||
RemoveTrackCluster(--nClusterCount);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1100,13 +995,8 @@ int MixerBoard::GetTrackClustersWidth()
|
||||
kDoubleInset; // plus final right margin
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MixerBoard::MoveTrackCluster(const Track* pTrack,
|
||||
void MixerBoard::MoveTrackCluster(const PlayableTrack* pTrack,
|
||||
bool bUp) // Up in TrackPanel is left in MixerBoard.
|
||||
#else
|
||||
void MixerBoard::MoveTrackCluster(const WaveTrack* pTrack,
|
||||
bool bUp) // Up in TrackPanel is left in MixerBoard.
|
||||
#endif
|
||||
{
|
||||
MixerTrackCluster* pMixerTrackCluster;
|
||||
int nIndex = FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
|
||||
@ -1140,18 +1030,21 @@ void MixerBoard::MoveTrackCluster(const WaveTrack* pTrack,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MixerBoard::RemoveTrackCluster(const Track* pTrack)
|
||||
#else
|
||||
void MixerBoard::RemoveTrackCluster(const WaveTrack* pTrack)
|
||||
#endif
|
||||
void MixerBoard::RemoveTrackCluster(const PlayableTrack* pTrack)
|
||||
{
|
||||
// Find and destroy.
|
||||
MixerTrackCluster* pMixerTrackCluster;
|
||||
int nIndex = this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
|
||||
|
||||
if (pMixerTrackCluster == NULL)
|
||||
return; // Couldn't find it.
|
||||
|
||||
RemoveTrackCluster(nIndex);
|
||||
}
|
||||
|
||||
void MixerBoard::RemoveTrackCluster(size_t nIndex)
|
||||
{
|
||||
auto pMixerTrackCluster = mMixerTrackClusters[nIndex];
|
||||
mMixerTrackClusters.RemoveAt(nIndex);
|
||||
pMixerTrackCluster->Destroy(); // DELETE is unsafe on wxWindow.
|
||||
|
||||
@ -1170,32 +1063,17 @@ void MixerBoard::RemoveTrackCluster(const WaveTrack* pTrack)
|
||||
}
|
||||
|
||||
this->UpdateWidth();
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
// Sanity check: if there is still a MixerTrackCluster with pTrack, then
|
||||
// we deleted the first but should have deleted the last:
|
||||
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
|
||||
assert(pMixerTrackCluster == NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const wxString & name)
|
||||
#else
|
||||
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const WaveTrack* pLeftTrack)
|
||||
#endif
|
||||
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const Track* pTrack)
|
||||
{
|
||||
if (mMusicalInstruments.empty())
|
||||
return NULL;
|
||||
|
||||
// random choice: return mMusicalInstruments[(int)pLeftTrack % mMusicalInstruments.GetCount()].mBitmap;
|
||||
// random choice: return mMusicalInstruments[(int)pTrack % mMusicalInstruments.GetCount()].mBitmap;
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
const wxString strTrackName(wxString{ name }.MakeLower());
|
||||
#else
|
||||
const wxString strTrackName(pLeftTrack->GetName().MakeLower());
|
||||
#endif
|
||||
const wxString strTrackName(pTrack->GetName().MakeLower());
|
||||
size_t nBestItemIndex = 0;
|
||||
unsigned int nBestScore = 0;
|
||||
unsigned int nInstrIndex = 0;
|
||||
@ -1236,17 +1114,15 @@ bool MixerBoard::HasSolo()
|
||||
{
|
||||
TrackListIterator iterTracks(mTracks);
|
||||
Track* pTrack;
|
||||
for (pTrack = iterTracks.First(); pTrack; pTrack = iterTracks.Next())
|
||||
if (pTrack->GetSolo())
|
||||
for (pTrack = iterTracks.First(); pTrack; pTrack = iterTracks.Next()) {
|
||||
auto pPlayable = dynamic_cast<PlayableTrack *>( pTrack );
|
||||
if (pPlayable && pPlayable->GetSolo())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MixerBoard::RefreshTrackCluster(const Track* pTrack, bool bEraseBackground /*= true*/)
|
||||
#else
|
||||
void MixerBoard::RefreshTrackCluster(const WaveTrack* pTrack, bool bEraseBackground )
|
||||
#endif
|
||||
void MixerBoard::RefreshTrackCluster(const PlayableTrack* pTrack, bool bEraseBackground /*= true*/)
|
||||
{
|
||||
MixerTrackCluster* pMixerTrackCluster;
|
||||
this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
|
||||
@ -1277,11 +1153,7 @@ void MixerBoard::ResetMeters(const bool bResetClipping)
|
||||
mMixerTrackClusters[i]->ResetMeter(bResetClipping);
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MixerBoard::UpdateName(const Track* pTrack)
|
||||
#else
|
||||
void MixerBoard::UpdateName(const WaveTrack* pTrack)
|
||||
#endif
|
||||
void MixerBoard::UpdateName(const PlayableTrack* pTrack)
|
||||
{
|
||||
MixerTrackCluster* pMixerTrackCluster;
|
||||
this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
|
||||
@ -1289,11 +1161,7 @@ void MixerBoard::UpdateName(const WaveTrack* pTrack)
|
||||
pMixerTrackCluster->UpdateName();
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MixerBoard::UpdateMute(const Track* pTrack /*= NULL*/) // NULL means update for all tracks.
|
||||
#else
|
||||
void MixerBoard::UpdateMute(const WaveTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
|
||||
#endif
|
||||
void MixerBoard::UpdateMute(const PlayableTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
|
||||
{
|
||||
if (pTrack == NULL)
|
||||
{
|
||||
@ -1309,11 +1177,7 @@ void MixerBoard::UpdateMute(const WaveTrack* pTrack /*= NULL*/) // NULL means up
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MixerBoard::UpdateSolo(const Track* pTrack /*= NULL*/) // NULL means update for all tracks.
|
||||
#else
|
||||
void MixerBoard::UpdateSolo(const WaveTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
|
||||
#endif
|
||||
void MixerBoard::UpdateSolo(const PlayableTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
|
||||
{
|
||||
if (pTrack == NULL)
|
||||
{
|
||||
@ -1329,11 +1193,7 @@ void MixerBoard::UpdateSolo(const WaveTrack* pTrack /*= NULL*/) // NULL means up
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MixerBoard::UpdatePan(const Track* pTrack)
|
||||
#else
|
||||
void MixerBoard::UpdatePan(const WaveTrack* pTrack)
|
||||
#endif
|
||||
void MixerBoard::UpdatePan(const PlayableTrack* pTrack)
|
||||
{
|
||||
MixerTrackCluster* pMixerTrackCluster;
|
||||
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
|
||||
@ -1341,11 +1201,7 @@ void MixerBoard::UpdatePan(const WaveTrack* pTrack)
|
||||
pMixerTrackCluster->UpdatePan();
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MixerBoard::UpdateGain(const Track* pTrack)
|
||||
#else
|
||||
void MixerBoard::UpdateGain(const WaveTrack* pTrack)
|
||||
#endif
|
||||
void MixerBoard::UpdateGain(const PlayableTrack* pTrack)
|
||||
{
|
||||
MixerTrackCluster* pMixerTrackCluster;
|
||||
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
|
||||
@ -1471,22 +1327,13 @@ void MixerBoard::CreateMuteSoloImages()
|
||||
mImageSoloDisabled = std::make_unique<wxImage>(mMuteSoloWidth, MUTE_SOLO_HEIGHT); // Leave empty because unused.
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
int MixerBoard::FindMixerTrackCluster(const Track* pTrack,
|
||||
MixerTrackCluster** hMixerTrackCluster) const
|
||||
#else
|
||||
int MixerBoard::FindMixerTrackCluster(const WaveTrack* pLeftTrack,
|
||||
int MixerBoard::FindMixerTrackCluster(const PlayableTrack* pTrack,
|
||||
MixerTrackCluster** hMixerTrackCluster) const
|
||||
#endif
|
||||
{
|
||||
*hMixerTrackCluster = NULL;
|
||||
for (unsigned int i = 0; i < mMixerTrackClusters.GetCount(); i++)
|
||||
{
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (mMixerTrackClusters[i]->mTrack == pTrack)
|
||||
#else
|
||||
if (mMixerTrackClusters[i]->mLeftTrack == pLeftTrack)
|
||||
#endif
|
||||
{
|
||||
*hMixerTrackCluster = mMixerTrackClusters[i];
|
||||
return i;
|
||||
|
@ -62,10 +62,11 @@ public:
|
||||
class AudacityProject;
|
||||
class Meter;
|
||||
class MixerBoard;
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
|
||||
class Track;
|
||||
class NoteTrack;
|
||||
#endif
|
||||
class PlayableTrack;
|
||||
|
||||
class WaveTrack;
|
||||
|
||||
class MixerTrackCluster final : public wxPanelWrapper
|
||||
@ -73,11 +74,15 @@ class MixerTrackCluster final : public wxPanelWrapper
|
||||
public:
|
||||
MixerTrackCluster(wxWindow* parent,
|
||||
MixerBoard* grandParent, AudacityProject* project,
|
||||
WaveTrack* pLeftTrack, WaveTrack* pRightTrack = NULL,
|
||||
PlayableTrack* pTrack,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize);
|
||||
virtual ~MixerTrackCluster() {}
|
||||
|
||||
WaveTrack *GetWave() const;
|
||||
WaveTrack *GetRight() const;
|
||||
NoteTrack *GetNote() const;
|
||||
|
||||
void UpdatePrefs();
|
||||
|
||||
void HandleResize(); // For wxSizeEvents, update gain slider and meter.
|
||||
@ -115,23 +120,7 @@ private:
|
||||
|
||||
|
||||
public:
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
// mTrack is redundant, but simplifies code that operates on either
|
||||
// mLeftTrack or mNoteTrack.
|
||||
Track* mTrack; // either mLeftTrack or mNoteTrack, whichever is not NULL
|
||||
#endif
|
||||
WaveTrack* mLeftTrack; // NULL if Note Track
|
||||
WaveTrack* mRightTrack; // NULL if mono
|
||||
|
||||
//vvv Vaughan, 2010-11-05:
|
||||
// I suggest that when this is no longer experimental, rather than all these #ifdef's,
|
||||
// this be done by factoring, i.e., add two subclasses to MixerTrackCluster,
|
||||
// MixerNoteTrackCluster and MixerWaveTrackCluster, such that all the common
|
||||
// code is in the parent, and these #ifdef's are only around
|
||||
// MixerNoteTrackCluster rather than sprinkled throughout MixerTrackCluster.
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
NoteTrack* mNoteTrack; // NULL if Wave Track
|
||||
#endif
|
||||
PlayableTrack * mTrack;
|
||||
|
||||
private:
|
||||
MixerBoard* mMixerBoard;
|
||||
@ -213,45 +202,26 @@ public:
|
||||
void UpdateTrackClusters();
|
||||
|
||||
int GetTrackClustersWidth();
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void MoveTrackCluster(const Track* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard.
|
||||
void RemoveTrackCluster(const Track* pTrack);
|
||||
void MoveTrackCluster(const PlayableTrack* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard.
|
||||
void RemoveTrackCluster(const PlayableTrack* pTrack);
|
||||
void RemoveTrackCluster(size_t nIndex);
|
||||
|
||||
|
||||
wxBitmap* GetMusicalInstrumentBitmap(const wxString & name);
|
||||
#else
|
||||
void MoveTrackCluster(const WaveTrack* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard.
|
||||
void RemoveTrackCluster(const WaveTrack* pTrack);
|
||||
|
||||
|
||||
wxBitmap* GetMusicalInstrumentBitmap(const WaveTrack* pLeftTrack);
|
||||
#endif
|
||||
wxBitmap* GetMusicalInstrumentBitmap(const Track *pTrack);
|
||||
|
||||
bool HasSolo();
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void RefreshTrackCluster(const Track* pTrack, bool bEraseBackground = true);
|
||||
#else
|
||||
void RefreshTrackCluster(const WaveTrack* pTrack, bool bEraseBackground = true);
|
||||
#endif
|
||||
void RefreshTrackCluster(const PlayableTrack* pTrack, bool bEraseBackground = true);
|
||||
void RefreshTrackClusters(bool bEraseBackground = true);
|
||||
void ResizeTrackClusters();
|
||||
|
||||
void ResetMeters(const bool bResetClipping);
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
void UpdateName(const Track* pTrack);
|
||||
void UpdateMute(const Track* pTrack = NULL); // NULL means update for all tracks.
|
||||
void UpdateSolo(const Track* pTrack = NULL); // NULL means update for all tracks.
|
||||
void UpdatePan(const Track* pTrack);
|
||||
void UpdateGain(const Track* pTrack);
|
||||
#else
|
||||
void UpdateName(const WaveTrack* pTrack);
|
||||
void UpdateMute(const WaveTrack* pTrack = NULL); // NULL means update for all tracks.
|
||||
void UpdateSolo(const WaveTrack* pTrack = NULL); // NULL means update for all tracks.
|
||||
void UpdatePan(const WaveTrack* pTrack);
|
||||
void UpdateGain(const WaveTrack* pTrack);
|
||||
#endif
|
||||
void UpdateName(const PlayableTrack* pTrack);
|
||||
void UpdateMute(const PlayableTrack* pTrack = NULL); // NULL means update for all tracks.
|
||||
void UpdateSolo(const PlayableTrack* pTrack = NULL); // NULL means update for all tracks.
|
||||
void UpdatePan(const PlayableTrack* pTrack);
|
||||
void UpdateGain(const PlayableTrack* pTrack);
|
||||
|
||||
void UpdateMeters(const double t1, const bool bLoopedPlay);
|
||||
|
||||
@ -259,13 +229,8 @@ public:
|
||||
|
||||
private:
|
||||
void CreateMuteSoloImages();
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
int FindMixerTrackCluster(const Track* pTrack,
|
||||
int FindMixerTrackCluster(const PlayableTrack* pTrack,
|
||||
MixerTrackCluster** hMixerTrackCluster) const;
|
||||
#else
|
||||
int FindMixerTrackCluster(const WaveTrack* pLeftTrack,
|
||||
MixerTrackCluster** hMixerTrackCluster) const;
|
||||
#endif
|
||||
void LoadMusicalInstruments();
|
||||
|
||||
// event handlers
|
||||
|
@ -103,8 +103,8 @@ NoteTrack::Holder TrackFactory::NewNoteTrack()
|
||||
return std::make_unique<NoteTrack>(mDirManager);
|
||||
}
|
||||
|
||||
NoteTrack::NoteTrack(const std::shared_ptr<DirManager> &projDirManager):
|
||||
Track(projDirManager)
|
||||
NoteTrack::NoteTrack(const std::shared_ptr<DirManager> &projDirManager)
|
||||
: NoteTrackBase(projDirManager)
|
||||
{
|
||||
SetDefaultName(_("Note Track"));
|
||||
SetName(GetDefaultName());
|
||||
@ -113,7 +113,7 @@ Track(projDirManager)
|
||||
mSerializationLength = 0;
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mGain = 0;
|
||||
mVelocity = 0;
|
||||
#endif
|
||||
mBottomNote = 24;
|
||||
mPitchHeight = 5;
|
||||
@ -137,7 +137,7 @@ Track::Holder NoteTrack::Duplicate() const
|
||||
// project object.
|
||||
if (mSeq) {
|
||||
SonifyBeginSerialize();
|
||||
assert(!mSerializationBuffer);
|
||||
wxASSERT(!mSerializationBuffer);
|
||||
// serialize from this to duplicate's mSerializationBuffer
|
||||
void *buffer;
|
||||
mSeq->serialize(&buffer,
|
||||
@ -146,13 +146,13 @@ Track::Holder NoteTrack::Duplicate() const
|
||||
SonifyEndSerialize();
|
||||
} else if (mSerializationBuffer) {
|
||||
SonifyBeginUnserialize();
|
||||
assert(!mSeq);
|
||||
wxASSERT(!mSeq);
|
||||
std::unique_ptr<Alg_track> alg_track{ Alg_seq::unserialize(mSerializationBuffer.get(),
|
||||
mSerializationLength) };
|
||||
assert(alg_track->get_type() == 's');
|
||||
wxASSERT(alg_track->get_type() == 's');
|
||||
duplicate->mSeq.reset(static_cast<Alg_seq*>(alg_track.release()));
|
||||
SonifyEndUnserialize();
|
||||
} else assert(false); // bug if neither mSeq nor mSerializationBuffer
|
||||
} else wxFAIL_MSG("neither mSeq nor mSerializationBuffer were present"); // bug if neither mSeq nor mSerializationBuffer
|
||||
// copy some other fields here
|
||||
duplicate->SetBottomNote(mBottomNote);
|
||||
duplicate->SetPitchHeight(mPitchHeight);
|
||||
@ -160,7 +160,7 @@ Track::Holder NoteTrack::Duplicate() const
|
||||
duplicate->mVisibleChannels = mVisibleChannels;
|
||||
duplicate->SetOffset(GetOffset());
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
duplicate->SetGain(GetGain());
|
||||
duplicate->SetVelocity(GetVelocity());
|
||||
#endif
|
||||
// This std::move is needed to "upcast" the pointer type
|
||||
return std::move(duplicate);
|
||||
@ -239,7 +239,7 @@ void NoteTrack::WarpAndTransposeNotes(double t0, double t1,
|
||||
|
||||
|
||||
|
||||
int NoteTrack::DrawLabelControls(wxDC & dc, wxRect & r)
|
||||
int NoteTrack::DrawLabelControls(wxDC & dc, const wxRect &r)
|
||||
{
|
||||
int wid = 23;
|
||||
int ht = 16;
|
||||
@ -328,7 +328,7 @@ int NoteTrack::DrawLabelControls(wxDC & dc, wxRect & r)
|
||||
return box.GetBottom();
|
||||
}
|
||||
|
||||
bool NoteTrack::LabelClick(wxRect & r, int mx, int my, bool right)
|
||||
bool NoteTrack::LabelClick(const wxRect &r, int mx, int my, bool right)
|
||||
{
|
||||
int wid = 23;
|
||||
int ht = 16;
|
||||
@ -758,6 +758,8 @@ bool NoteTrack::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
||||
double dblValue;
|
||||
if (!wxStrcmp(attr, wxT("name")) && XMLValueChecker::IsGoodString(strValue))
|
||||
mName = strValue;
|
||||
else if (this->NoteTrackBase::HandleXMLAttribute(attr, value))
|
||||
{}
|
||||
else if (!wxStrcmp(attr, wxT("offset")) &&
|
||||
XMLValueChecker::IsGoodString(strValue) &&
|
||||
Internat::CompatibleToDouble(strValue, &dblValue))
|
||||
@ -782,7 +784,7 @@ bool NoteTrack::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
||||
else if (!wxStrcmp(attr, wxT("velocity")) &&
|
||||
XMLValueChecker::IsGoodString(strValue) &&
|
||||
Internat::CompatibleToDouble(strValue, &dblValue))
|
||||
mGain = (float) dblValue;
|
||||
mVelocity = (float) dblValue;
|
||||
#endif
|
||||
else if (!wxStrcmp(attr, wxT("bottomnote")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
|
||||
@ -826,11 +828,12 @@ void NoteTrack::WriteXML(XMLWriter &xmlFile) const
|
||||
if (!mSeq) { // replace saveme with an (unserialized) duplicate
|
||||
holder = Duplicate();
|
||||
saveme = static_cast<NoteTrack*>(holder.get());
|
||||
assert(saveme->mSeq);
|
||||
wxASSERT(saveme->mSeq);
|
||||
}
|
||||
saveme->mSeq->write(data, true);
|
||||
xmlFile.StartTag(wxT("notetrack"));
|
||||
xmlFile.WriteAttr(wxT("name"), saveme->mName);
|
||||
this->NoteTrackBase::WriteXMLAttributes(xmlFile);
|
||||
xmlFile.WriteAttr(wxT("offset"), saveme->GetOffset());
|
||||
xmlFile.WriteAttr(wxT("visiblechannels"), saveme->mVisibleChannels);
|
||||
xmlFile.WriteAttr(wxT("height"), saveme->GetActualHeight());
|
||||
@ -838,7 +841,7 @@ void NoteTrack::WriteXML(XMLWriter &xmlFile) const
|
||||
xmlFile.WriteAttr(wxT("isSelected"), this->GetSelected());
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
xmlFile.WriteAttr(wxT("velocity"), (double) saveme->mGain);
|
||||
xmlFile.WriteAttr(wxT("velocity"), (double) saveme->mVelocity);
|
||||
#endif
|
||||
xmlFile.WriteAttr(wxT("bottomnote"), saveme->mBottomNote);
|
||||
xmlFile.WriteAttr(wxT("data"), wxString(data.str().c_str(), wxConvUTF8));
|
||||
|
@ -50,7 +50,17 @@ class wxRect;
|
||||
class DirManager;
|
||||
class Alg_seq; // from "allegro.h"
|
||||
|
||||
class AUDACITY_DLL_API NoteTrack final : public Track {
|
||||
using NoteTrackBase =
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
PlayableTrack
|
||||
#else
|
||||
AudioTrack
|
||||
#endif
|
||||
;
|
||||
|
||||
class AUDACITY_DLL_API NoteTrack final
|
||||
: public NoteTrackBase
|
||||
{
|
||||
public:
|
||||
friend class TrackArtist;
|
||||
|
||||
@ -69,8 +79,8 @@ class AUDACITY_DLL_API NoteTrack final : public Track {
|
||||
void WarpAndTransposeNotes(double t0, double t1,
|
||||
const TimeWarper &warper, double semitones);
|
||||
|
||||
int DrawLabelControls(wxDC & dc, wxRect & r);
|
||||
bool LabelClick(wxRect & r, int x, int y, bool right);
|
||||
int DrawLabelControls(wxDC & dc, const wxRect &r);
|
||||
bool LabelClick(const wxRect &rect, int x, int y, bool right);
|
||||
|
||||
void SetSequence(std::unique_ptr<Alg_seq> &&seq);
|
||||
Alg_seq* GetSequence();
|
||||
@ -98,8 +108,8 @@ class AUDACITY_DLL_API NoteTrack final : public Track {
|
||||
bool Shift(double t) /* not override */;
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
float GetGain() const { return mGain; }
|
||||
void SetGain(float gain) { mGain = gain; }
|
||||
float GetVelocity() const { return mVelocity; }
|
||||
void SetVelocity(float velocity) { mVelocity = velocity; }
|
||||
#endif
|
||||
|
||||
double NearestBeatTime(double time, double *beat) const;
|
||||
@ -202,7 +212,7 @@ class AUDACITY_DLL_API NoteTrack final : public Track {
|
||||
long mSerializationLength;
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
float mGain; // velocity offset
|
||||
float mVelocity; // velocity offset
|
||||
#endif
|
||||
|
||||
// mBottom is the Y offset of pitch 0 (normally off screen)
|
||||
|
113
src/Project.cpp
113
src/Project.cpp
@ -2800,7 +2800,7 @@ wxArrayString AudacityProject::ShowOpenDialog(const wxString &extraformat, const
|
||||
wxArrayString selected;
|
||||
|
||||
FileDialog dlog(NULL,
|
||||
_("Select one or more audio files..."),
|
||||
_("Select one or more files"),
|
||||
path,
|
||||
wxT(""),
|
||||
mask,
|
||||
@ -3655,6 +3655,8 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCompressed)
|
||||
while (t) {
|
||||
if ((t->GetKind() == Track::Wave) && bWantSaveCompressed)
|
||||
{
|
||||
auto wt = static_cast<const WaveTrack *>(t);
|
||||
|
||||
//vvv This should probably be a method, WaveTrack::WriteCompressedTrackXML().
|
||||
xmlFile.StartTag(wxT("import"));
|
||||
xmlFile.WriteAttr(wxT("filename"), mStrOtherNamesArray[ndx]); // Assumes mTracks order hasn't changed!
|
||||
@ -3665,8 +3667,8 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCompressed)
|
||||
// xmlFile.WriteAttr(wxT("linked"), t->GetLinked());
|
||||
|
||||
xmlFile.WriteAttr(wxT("offset"), t->GetOffset(), 8);
|
||||
xmlFile.WriteAttr(wxT("mute"), t->GetMute());
|
||||
xmlFile.WriteAttr(wxT("solo"), t->GetSolo());
|
||||
xmlFile.WriteAttr(wxT("mute"), wt->GetMute());
|
||||
xmlFile.WriteAttr(wxT("solo"), wt->GetSolo());
|
||||
xmlFile.WriteAttr(wxT("height"), t->GetActualHeight());
|
||||
xmlFile.WriteAttr(wxT("minimized"), t->GetMinimized());
|
||||
|
||||
@ -3975,10 +3977,12 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
|
||||
((pTrack != NULL) && (pSavedTrack != NULL));
|
||||
pTrack = iter.Next(), pSavedTrack = savedTrackIter.Next())
|
||||
{
|
||||
pWaveTrack = (WaveTrack*)pTrack;
|
||||
pWaveTrack = static_cast<WaveTrack*>(pTrack);
|
||||
auto pSavedWaveTrack = static_cast<const WaveTrack*>(pSavedTrack);
|
||||
|
||||
pWaveTrack->SetSelected(pSavedTrack->GetSelected());
|
||||
pWaveTrack->SetMute(pSavedTrack->GetMute());
|
||||
pWaveTrack->SetSolo(pSavedTrack->GetSolo());
|
||||
pWaveTrack->SetMute(pSavedWaveTrack->GetMute());
|
||||
pWaveTrack->SetSolo(pSavedWaveTrack->GetSolo());
|
||||
|
||||
pWaveTrack->SetGain(((WaveTrack*)pSavedTrack)->GetGain());
|
||||
pWaveTrack->SetPan(((WaveTrack*)pSavedTrack)->GetPan());
|
||||
@ -5396,12 +5400,13 @@ void AudacityProject::RemoveTrack(Track * toRemove)
|
||||
wxString name = toRemove->GetName();
|
||||
Track *partner = toRemove->GetLink();
|
||||
|
||||
if (toRemove->GetKind() == Track::Wave)
|
||||
auto playable = dynamic_cast<PlayableTrack*>(toRemove);
|
||||
if (playable)
|
||||
{
|
||||
// Update mixer board displayed tracks.
|
||||
MixerBoard* pMixerBoard = this->GetMixerBoard();
|
||||
if (pMixerBoard)
|
||||
pMixerBoard->RemoveTrackCluster((WaveTrack*)toRemove); // Will remove partner shown in same cluster.
|
||||
pMixerBoard->RemoveTrackCluster(playable); // Will remove partner shown in same cluster.
|
||||
}
|
||||
|
||||
mTracks->Remove(toRemove);
|
||||
@ -5429,36 +5434,45 @@ void AudacityProject::HandleTrackMute(Track *t, const bool exclusive)
|
||||
if (exclusive)
|
||||
{
|
||||
TrackListIterator iter(GetTracks());
|
||||
Track *i = iter.First();
|
||||
while (i) {
|
||||
if (i == t) {
|
||||
i->SetMute(true);
|
||||
if(i->GetLinked()) { // also mute the linked track
|
||||
i = iter.Next();
|
||||
Track *it = iter.First();
|
||||
while (it) {
|
||||
auto i = dynamic_cast<PlayableTrack *>(it);
|
||||
if (i) {
|
||||
if (i == t) {
|
||||
i->SetMute(true);
|
||||
if(i->GetLinked()) { // also mute the linked track
|
||||
it = iter.Next();
|
||||
i->SetMute(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
i->SetMute(false);
|
||||
}
|
||||
i->SetSolo(false);
|
||||
}
|
||||
else {
|
||||
i->SetMute(false);
|
||||
}
|
||||
i->SetSolo(false);
|
||||
i = iter.Next();
|
||||
it = iter.Next();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal click toggles this track.
|
||||
t->SetMute(!t->GetMute());
|
||||
auto pt = dynamic_cast<PlayableTrack *>( t );
|
||||
if (!pt)
|
||||
return;
|
||||
|
||||
pt->SetMute(!pt->GetMute());
|
||||
if(t->GetLinked()) // set mute the same on both, if a pair
|
||||
{
|
||||
bool muted = t->GetMute();
|
||||
bool muted = pt->GetMute();
|
||||
TrackListIterator iter(GetTracks());
|
||||
Track *i = iter.First();
|
||||
while (i != t) { // search for this track
|
||||
i = iter.Next();
|
||||
}
|
||||
i = iter.Next(); // get the next one, since linked
|
||||
i->SetMute(muted); // and mute it as well
|
||||
auto pi = dynamic_cast<PlayableTrack *>( i );
|
||||
if (pi)
|
||||
pi->SetMute(muted); // and mute it as well
|
||||
}
|
||||
|
||||
if (IsSoloSimple() || IsSoloNone())
|
||||
@ -5470,18 +5484,23 @@ void AudacityProject::HandleTrackMute(Track *t, const bool exclusive)
|
||||
// We also set a solo indicator if we have just one track / stereo pair playing.
|
||||
// otherwise clear solo on everything.
|
||||
while (i) {
|
||||
if( !i->GetMute())
|
||||
{
|
||||
nPlaying += 1;
|
||||
if(i->GetLinked())
|
||||
i = iter.Next(); // don't count this one as it is linked
|
||||
auto pi = dynamic_cast<PlayableTrack *>( i );
|
||||
if (pi) {
|
||||
if( !pi->GetMute())
|
||||
{
|
||||
nPlaying += 1;
|
||||
if(i->GetLinked())
|
||||
i = iter.Next(); // don't count this one as it is linked
|
||||
}
|
||||
}
|
||||
i = iter.Next();
|
||||
}
|
||||
|
||||
i = iter.First();
|
||||
while (i) {
|
||||
i->SetSolo( (nPlaying==1) && !i->GetMute() ); // will set both of a stereo pair
|
||||
auto pi = dynamic_cast<PlayableTrack *>( i );
|
||||
if (pi)
|
||||
pi->SetSolo( (nPlaying==1) && !pi->GetMute() ); // will set both of a stereo pair
|
||||
i = iter.Next();
|
||||
}
|
||||
}
|
||||
@ -5491,8 +5510,12 @@ void AudacityProject::HandleTrackMute(Track *t, const bool exclusive)
|
||||
|
||||
// Type of solo (standard or simple) follows the set preference, unless
|
||||
// alternate == true, which causes the opposite behavior.
|
||||
void AudacityProject::HandleTrackSolo(Track *t, const bool alternate)
|
||||
void AudacityProject::HandleTrackSolo(Track *const t, const bool alternate)
|
||||
{
|
||||
const auto pt = dynamic_cast<PlayableTrack *>( t );
|
||||
if (!pt)
|
||||
return;
|
||||
|
||||
bool bSoloMultiple = !IsSoloSimple() ^ alternate;
|
||||
|
||||
// Standard and Simple solo have opposite defaults:
|
||||
@ -5502,17 +5525,19 @@ void AudacityProject::HandleTrackSolo(Track *t, const bool alternate)
|
||||
// when in standard radio button mode.
|
||||
if ( bSoloMultiple )
|
||||
{
|
||||
t->SetSolo( !t->GetSolo() );
|
||||
pt->SetSolo( !pt->GetSolo() );
|
||||
if(t->GetLinked())
|
||||
{
|
||||
bool soloed = t->GetSolo();
|
||||
bool soloed = pt->GetSolo();
|
||||
TrackListIterator iter(GetTracks());
|
||||
Track *i = iter.First();
|
||||
while (i != t) { // search for this track
|
||||
i = iter.Next();
|
||||
}
|
||||
i = iter.Next(); // get the next one, since linked
|
||||
i->SetSolo(soloed); // and solo it as well
|
||||
auto pi = dynamic_cast<PlayableTrack *>( i );
|
||||
if (pi)
|
||||
pi->SetSolo(soloed); // and solo it as well
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -5521,26 +5546,32 @@ void AudacityProject::HandleTrackSolo(Track *t, const bool alternate)
|
||||
// OR unmute and unsolo everything.
|
||||
TrackListIterator iter(GetTracks());
|
||||
Track *i = iter.First();
|
||||
bool bWasSolo = t->GetSolo();
|
||||
bool bWasSolo = pt->GetSolo();
|
||||
while (i) {
|
||||
if( i==t )
|
||||
{
|
||||
i->SetSolo(!bWasSolo);
|
||||
pt->SetSolo(!bWasSolo);
|
||||
if( IsSoloSimple() )
|
||||
i->SetMute(false);
|
||||
pt->SetMute(false);
|
||||
if(t->GetLinked())
|
||||
{
|
||||
i = iter.Next();
|
||||
i->SetSolo(!bWasSolo);
|
||||
if( IsSoloSimple() )
|
||||
i->SetMute(false);
|
||||
auto pi = dynamic_cast<PlayableTrack *>( i );
|
||||
if (pi) {
|
||||
pi->SetSolo(!bWasSolo);
|
||||
if( IsSoloSimple() )
|
||||
pi->SetMute(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i->SetSolo(false);
|
||||
if( IsSoloSimple() )
|
||||
i->SetMute(!bWasSolo);
|
||||
auto pi = dynamic_cast<PlayableTrack *>( i );
|
||||
if (pi) {
|
||||
pi->SetSolo(false);
|
||||
if( IsSoloSimple() )
|
||||
pi->SetMute(!bWasSolo);
|
||||
}
|
||||
}
|
||||
i = iter.Next();
|
||||
}
|
||||
|
@ -378,8 +378,10 @@ float Sequence::GetRMS(sampleCount start, sampleCount len, bool mayThrow) const
|
||||
|
||||
std::unique_ptr<Sequence> Sequence::Copy(sampleCount s0, sampleCount s1) const
|
||||
{
|
||||
if (s0 >= s1 || s0 >= mNumSamples || s1 < 0)
|
||||
return {};
|
||||
auto dest = std::make_unique<Sequence>(mDirManager, mSampleFormat);
|
||||
if (s0 >= s1 || s0 >= mNumSamples || s1 < 0) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
int numBlocks = mBlock.size();
|
||||
|
||||
@ -391,7 +393,6 @@ std::unique_ptr<Sequence> Sequence::Copy(sampleCount s0, sampleCount s1) const
|
||||
wxUnusedVar(numBlocks);
|
||||
wxASSERT(b0 <= b1);
|
||||
|
||||
auto dest = std::make_unique<Sequence>(mDirManager, mSampleFormat);
|
||||
dest->mBlock.reserve(b1 - b0 + 1);
|
||||
|
||||
SampleBuffer buffer(mMaxSamples, mSampleFormat);
|
||||
|
@ -50,8 +50,6 @@ Track::Track(const std::shared_ptr<DirManager> &projDirManager)
|
||||
mList = NULL;
|
||||
mSelected = false;
|
||||
mLinked = false;
|
||||
mMute = false;
|
||||
mSolo = false;
|
||||
|
||||
mY = 0;
|
||||
mHeight = 150;
|
||||
@ -92,8 +90,6 @@ void Track::Init(const Track &orig)
|
||||
|
||||
mSelected = orig.mSelected;
|
||||
mLinked = orig.mLinked;
|
||||
mMute = orig.mMute;
|
||||
mSolo = orig.mSolo;
|
||||
mHeight = orig.mHeight;
|
||||
mMinimized = orig.mMinimized;
|
||||
mChannel = orig.mChannel;
|
||||
@ -112,8 +108,6 @@ void Track::SetSelected(bool s)
|
||||
void Track::Merge(const Track &orig)
|
||||
{
|
||||
mSelected = orig.mSelected;
|
||||
mMute = orig.mMute;
|
||||
mSolo = orig.mSolo;
|
||||
}
|
||||
|
||||
Track::~Track()
|
||||
@ -331,6 +325,49 @@ bool Track::SyncLockAdjust(double oldT1, double newT1)
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlayableTrack::Init( const PlayableTrack &orig )
|
||||
{
|
||||
mMute = orig.mMute;
|
||||
mSolo = orig.mSolo;
|
||||
AudioTrack::Init( orig );
|
||||
}
|
||||
|
||||
void PlayableTrack::Merge( const Track &orig )
|
||||
{
|
||||
auto pOrig = dynamic_cast<const PlayableTrack *>(&orig);
|
||||
wxASSERT( pOrig );
|
||||
mMute = pOrig->mMute;
|
||||
mSolo = pOrig->mSolo;
|
||||
AudioTrack::Merge( *pOrig );
|
||||
}
|
||||
|
||||
// Serialize, not with tags of its own, but as attributes within a tag.
|
||||
void PlayableTrack::WriteXMLAttributes(XMLWriter &xmlFile) const
|
||||
{
|
||||
xmlFile.WriteAttr(wxT("mute"), mMute);
|
||||
xmlFile.WriteAttr(wxT("solo"), mSolo);
|
||||
AudioTrack::WriteXMLAttributes(xmlFile);
|
||||
}
|
||||
|
||||
// Return true iff the attribute is recognized.
|
||||
bool PlayableTrack::HandleXMLAttribute(const wxChar *attr, const wxChar *value)
|
||||
{
|
||||
const wxString strValue{ value };
|
||||
long nValue;
|
||||
if (!wxStrcmp(attr, wxT("mute")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) {
|
||||
mMute = (nValue != 0);
|
||||
return true;
|
||||
}
|
||||
else if (!wxStrcmp(attr, wxT("solo")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) {
|
||||
mSolo = (nValue != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return AudioTrack::HandleXMLAttribute(attr, value);
|
||||
}
|
||||
|
||||
// TrackListIterator
|
||||
TrackListIterator::TrackListIterator(TrackList * val)
|
||||
: l(val)
|
||||
@ -579,16 +616,9 @@ SyncLockedTracksIterator::SyncLockedTracksIterator(TrackList * val)
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool IsSyncLockableNonLabelTrack( const Track *pTrack )
|
||||
inline bool IsSyncLockableNonLabelTrack( const Track *pTrack )
|
||||
{
|
||||
if ( pTrack->GetKind() == Track::Wave )
|
||||
return true;
|
||||
#ifdef USE_MIDI
|
||||
else if ( pTrack->GetKind() == Track::Note )
|
||||
return true;
|
||||
#endif
|
||||
else
|
||||
return false;
|
||||
return nullptr != dynamic_cast< const AudioTrack * >( pTrack );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1208,7 +1238,9 @@ unsigned TrackList::GetNumExportChannels(bool selectionOnly) const
|
||||
for (tr = iter.First(this); tr != NULL; tr = iter.Next()) {
|
||||
|
||||
// Want only unmuted wave tracks.
|
||||
if ((tr->GetKind() != Track::Wave) || tr->GetMute())
|
||||
auto wt = static_cast<const WaveTrack *>(tr);
|
||||
if ((tr->GetKind() != Track::Wave) ||
|
||||
wt->GetMute())
|
||||
continue;
|
||||
|
||||
// do we only want selected ones?
|
||||
@ -1265,8 +1297,9 @@ namespace {
|
||||
|
||||
for (; p != end; ++p) {
|
||||
const auto &track = *p;
|
||||
auto wt = static_cast<const WaveTrack *>(&*track);
|
||||
if (track->GetKind() == Track::Wave &&
|
||||
(includeMuted || !track->GetMute()) &&
|
||||
(includeMuted || !wt->GetMute()) &&
|
||||
(track->GetSelected() || !selectionOnly)) {
|
||||
waveTrackArray.push_back(static_cast<WaveTrack*>(track.get()));
|
||||
}
|
||||
|
47
src/Track.h
47
src/Track.h
@ -140,8 +140,6 @@ class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler
|
||||
protected:
|
||||
int mChannel;
|
||||
double mOffset;
|
||||
bool mMute;
|
||||
bool mSolo;
|
||||
|
||||
mutable std::shared_ptr<DirManager> mDirManager;
|
||||
|
||||
@ -189,14 +187,10 @@ class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler
|
||||
void SetDefaultName( const wxString &n ) { mDefaultName = n; }
|
||||
|
||||
bool GetSelected() const { return mSelected; }
|
||||
bool GetMute () const { return mMute; }
|
||||
bool GetLinked () const { return mLinked; }
|
||||
bool GetSolo () const { return mSolo; }
|
||||
|
||||
virtual void SetSelected(bool s);
|
||||
void SetMute (bool m) { mMute = m; }
|
||||
void SetLinked (bool l);
|
||||
void SetSolo (bool s) { mSolo = s; }
|
||||
|
||||
int GetChannel() const { return mChannel; }
|
||||
virtual double GetOffset() const = 0;
|
||||
@ -251,6 +245,47 @@ class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler
|
||||
bool IsSyncLockSelected() const;
|
||||
};
|
||||
|
||||
class AudioTrack /* not final */ : public Track
|
||||
{
|
||||
public:
|
||||
AudioTrack(const std::shared_ptr<DirManager> &projDirManager)
|
||||
: Track{ projDirManager } {}
|
||||
AudioTrack(const Track &orig) : Track{ orig } {}
|
||||
|
||||
// Serialize, not with tags of its own, but as attributes within a tag.
|
||||
void WriteXMLAttributes(XMLWriter &xmlFile) const {}
|
||||
|
||||
// Return true iff the attribute is recognized.
|
||||
bool HandleXMLAttribute(const wxChar * /*attr*/, const wxChar * /*value*/)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
class PlayableTrack /* not final */ : public AudioTrack
|
||||
{
|
||||
public:
|
||||
PlayableTrack(const std::shared_ptr<DirManager> &projDirManager)
|
||||
: AudioTrack{ projDirManager } {}
|
||||
PlayableTrack(const Track &orig) : AudioTrack{ orig } {}
|
||||
|
||||
bool GetMute () const { return mMute; }
|
||||
bool GetSolo () const { return mSolo; }
|
||||
void SetMute (bool m) { mMute = m; }
|
||||
void SetSolo (bool s) { mSolo = s; }
|
||||
|
||||
void Init( const PlayableTrack &init );
|
||||
void Merge( const Track &init ) override;
|
||||
|
||||
// Serialize, not with tags of its own, but as attributes within a tag.
|
||||
void WriteXMLAttributes(XMLWriter &xmlFile) const;
|
||||
|
||||
// Return true iff the attribute is recognized.
|
||||
bool HandleXMLAttribute(const wxChar *attr, const wxChar *value);
|
||||
|
||||
protected:
|
||||
bool mMute { false };
|
||||
bool mSolo { false };
|
||||
};
|
||||
|
||||
class AUDACITY_DLL_API TrackListIterator /* not final */
|
||||
{
|
||||
public:
|
||||
|
@ -336,7 +336,8 @@ void TrackArtist::DrawTracks(TrackList * tracks,
|
||||
|
||||
bool hasSolo = false;
|
||||
for (t = iter.First(); t; t = iter.Next()) {
|
||||
if (t->GetSolo()) {
|
||||
auto pt = dynamic_cast<const PlayableTrack *>(t);
|
||||
if (pt && pt->GetSolo()) {
|
||||
hasSolo = true;
|
||||
break;
|
||||
}
|
||||
@ -457,7 +458,8 @@ void TrackArtist::DrawTrack(const Track * t,
|
||||
clip->ClearDisplayRect();
|
||||
}
|
||||
|
||||
bool muted = (hasSolo || t->GetMute()) && !t->GetSolo();
|
||||
bool muted = (hasSolo || wt->GetMute()) &&
|
||||
!wt->GetSolo();
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
wxAntialiasMode aamode = dc.GetGraphicsContext()->GetAntialiasMode();
|
||||
@ -493,7 +495,11 @@ void TrackArtist::DrawTrack(const Track * t,
|
||||
#ifdef USE_MIDI
|
||||
case Track::Note:
|
||||
{
|
||||
bool muted = (hasSolo || t->GetMute()) && !t->GetSolo();
|
||||
auto nt = static_cast<const NoteTrack *>(t);
|
||||
bool muted = false;
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
muted = (hasSolo || nt->GetMute()) && !nt->GetSolo();
|
||||
#endif
|
||||
DrawNoteTrack((NoteTrack *)t, dc, rect, selectedRegion, zoomInfo, muted);
|
||||
break;
|
||||
}
|
||||
@ -2807,17 +2813,17 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track,
|
||||
|
||||
Alg_seq_ptr seq = track->mSeq.get();
|
||||
if (!seq) {
|
||||
assert(track->mSerializationBuffer);
|
||||
wxASSERT(track->mSerializationBuffer);
|
||||
// JKC: Previously this indirected via seq->, a NULL pointer.
|
||||
// This was actually OK, since unserialize is a static function.
|
||||
// Alg_seq:: is clearer.
|
||||
std::unique_ptr<Alg_track> alg_track{ Alg_seq::unserialize(track->mSerializationBuffer.get(),
|
||||
track->mSerializationLength) };
|
||||
assert(alg_track->get_type() == 's');
|
||||
wxASSERT(alg_track->get_type() == 's');
|
||||
const_cast<NoteTrack*>(track)->mSeq.reset(seq = static_cast<Alg_seq*>(alg_track.release()));
|
||||
track->mSerializationBuffer.reset();
|
||||
}
|
||||
assert(seq);
|
||||
wxASSERT(seq);
|
||||
int visibleChannels = track->mVisibleChannels;
|
||||
|
||||
if (!track->GetSelected())
|
||||
|
@ -3732,8 +3732,11 @@ void TrackPanel::DoSlide(wxMouseEvent & event)
|
||||
#else
|
||||
{
|
||||
trySnap = true;
|
||||
desiredSlideAmount = rint(mouseTrack->GetRate() * desiredSlideAmount) /
|
||||
mouseTrack->GetRate(); // set it to a sample point
|
||||
if (mouseTrack->GetKind() == Track::Wave) {
|
||||
WaveTrack *mtw = (WaveTrack *)mouseTrack;
|
||||
desiredSlideAmount = rint(mtw->GetRate() * desiredSlideAmount) /
|
||||
mtw->GetRate(); // set it to a sample point
|
||||
}
|
||||
if (mSnapManager && mCapturedClip) {
|
||||
clipLeft = mCapturedClip->GetStartTime() + desiredSlideAmount;
|
||||
clipRight = mCapturedClip->GetEndTime() + desiredSlideAmount;
|
||||
@ -4960,7 +4963,7 @@ void TrackPanel::HandleSliders(wxMouseEvent &event, bool pan)
|
||||
// mCapturedTrack is not wave...
|
||||
if (!pan) {
|
||||
// .. so assume it is note
|
||||
static_cast<NoteTrack*>(mCapturedTrack)->SetGain(newValue);
|
||||
static_cast<NoteTrack*>(mCapturedTrack)->SetVelocity(newValue);
|
||||
#ifdef EXPERIMENTAL_MIXER_BOARD
|
||||
if (pMixerBoard)
|
||||
// probably should modify UpdateGain to take a track that is
|
||||
@ -5209,27 +5212,17 @@ void TrackPanel::HandleRearrange(wxMouseEvent & event)
|
||||
if (event.m_y < mMoveUpThreshold || event.m_y < 0) {
|
||||
mTracks->MoveUp(mCapturedTrack);
|
||||
--mRearrangeCount;
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (pMixerBoard && (mCapturedTrack->GetKind() == Track::Wave ||
|
||||
mCapturedTrack->GetKind() == Track::Note))
|
||||
pMixerBoard->MoveTrackCluster(mCapturedTrack, true /* up */);
|
||||
#else
|
||||
if (pMixerBoard && (mCapturedTrack->GetKind() == Track::Wave))
|
||||
pMixerBoard->MoveTrackCluster((WaveTrack*)mCapturedTrack, true /* up */);
|
||||
#endif
|
||||
if (pMixerBoard)
|
||||
if(auto pPlayable = dynamic_cast< const PlayableTrack* >( mCapturedTrack ))
|
||||
pMixerBoard->MoveTrackCluster(pPlayable, true /* up */);
|
||||
}
|
||||
else if (event.m_y > mMoveDownThreshold || event.m_y > GetRect().GetHeight()) {
|
||||
mTracks->MoveDown(mCapturedTrack);
|
||||
++mRearrangeCount;
|
||||
/* i18n-hint: a direction as in up or down.*/
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (pMixerBoard && (mCapturedTrack->GetKind() == Track::Wave ||
|
||||
mCapturedTrack->GetKind() == Track::Note))
|
||||
pMixerBoard->MoveTrackCluster(mCapturedTrack, false /* down */);
|
||||
#else
|
||||
if (pMixerBoard && (mCapturedTrack->GetKind() == Track::Wave))
|
||||
pMixerBoard->MoveTrackCluster((WaveTrack*)mCapturedTrack, false /* down */);
|
||||
#endif
|
||||
if (pMixerBoard)
|
||||
if(auto pPlayable = dynamic_cast< const PlayableTrack* >( mCapturedTrack ))
|
||||
pMixerBoard->MoveTrackCluster(pPlayable, false /* down */);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -9295,18 +9288,19 @@ void TrackInfo::DrawMuteSolo(wxDC * dc, const wxRect & rect, Track * t,
|
||||
return; // don't draw mute and solo buttons, because they don't fit into track label
|
||||
|
||||
AColor::MediumTrackInfo( dc, t->GetSelected());
|
||||
auto pt = dynamic_cast<const PlayableTrack *>(t);
|
||||
if( solo )
|
||||
{
|
||||
if( t->GetSolo() )
|
||||
if( pt && pt->GetSolo() )
|
||||
{
|
||||
AColor::Solo(dc, t->GetSolo(), t->GetSelected());
|
||||
AColor::Solo(dc, pt->GetSolo(), t->GetSelected());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( t->GetMute() )
|
||||
if( pt && pt->GetMute() )
|
||||
{
|
||||
AColor::Mute(dc, t->GetMute(), t->GetSelected(), t->GetSolo());
|
||||
AColor::Mute(dc, pt->GetMute(), t->GetSelected(), pt->GetSolo());
|
||||
}
|
||||
}
|
||||
//(solo) ? AColor::Solo(dc, t->GetSolo(), t->GetSelected()) :
|
||||
@ -9325,7 +9319,11 @@ void TrackInfo::DrawMuteSolo(wxDC * dc, const wxRect & rect, Track * t,
|
||||
dc->GetTextExtent(str, &textWidth, &textHeight);
|
||||
dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2);
|
||||
|
||||
AColor::BevelTrackInfo(*dc, (solo?t->GetSolo():t->GetMute()) == down, bev);
|
||||
AColor::BevelTrackInfo(
|
||||
*dc,
|
||||
(solo ? pt->GetSolo() : (pt && pt->GetMute())) == down,
|
||||
bev
|
||||
);
|
||||
|
||||
if (solo && !down) {
|
||||
// Update the mute button, which may be grayed out depending on
|
||||
@ -9374,7 +9372,7 @@ void TrackInfo::DrawVelocitySlider(wxDC *dc, NoteTrack *t, wxRect rect) const
|
||||
auto &gain = mGain; // mGains[index];
|
||||
gain->SetStyle(VEL_SLIDER);
|
||||
GainSlider(index)->Move(wxPoint(gainRect.x, gainRect.y));
|
||||
GainSlider(index)->Set(t->GetGain());
|
||||
GainSlider(index)->Set(t->GetVelocity());
|
||||
GainSlider(index)->OnPaint(*dc
|
||||
// , t->GetSelected()
|
||||
);
|
||||
|
@ -353,15 +353,18 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name )
|
||||
this is a Time track.*/
|
||||
name->Append( wxT(" ") + wxString(_("Time Track")));
|
||||
}
|
||||
#ifdef USE_MIDI
|
||||
else if (t->GetKind() == Track::Note)
|
||||
{
|
||||
/* i18n-hint: This is for screen reader software and indicates that
|
||||
this is a Note track.*/
|
||||
name->Append( wxT(" ") + wxString(_("Note Track")));
|
||||
}
|
||||
#endif
|
||||
|
||||
// LLL: Remove these during "refactor"
|
||||
if( t->GetMute() )
|
||||
auto pt = dynamic_cast<PlayableTrack *>(t);
|
||||
if( pt && pt->GetMute() )
|
||||
{
|
||||
// The following comment also applies to the solo, selected,
|
||||
// and synclockselected states.
|
||||
@ -374,7 +377,7 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name )
|
||||
name->Append( wxT(" ") + wxString(_( " Mute On" )) );
|
||||
}
|
||||
|
||||
if( t->GetSolo() )
|
||||
if( pt && pt->GetSolo() )
|
||||
{
|
||||
/* i18n-hint: This is for screen reader software and indicates that
|
||||
on this track solo is on.*/
|
||||
@ -545,12 +548,13 @@ wxAccStatus TrackPanelAx::GetValue( int WXUNUSED(childId), wxString* WXUNUSED(st
|
||||
}
|
||||
|
||||
// LLL: Remove these during "refactor"
|
||||
if( t->GetMute() )
|
||||
auto pt = dynamic_cast<PlayableTrack *>(t);
|
||||
if( pt && pt->GetMute() )
|
||||
{
|
||||
strValue->Append( _( " Mute On" ) );
|
||||
}
|
||||
|
||||
if( t->GetSolo() )
|
||||
if( pt && pt->GetSolo() )
|
||||
{
|
||||
strValue->Append( _( " Solo On" ) );
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ WaveTrack::Holder TrackFactory::NewWaveTrack(sampleFormat format, double rate)
|
||||
}
|
||||
|
||||
WaveTrack::WaveTrack(const std::shared_ptr<DirManager> &projDirManager, sampleFormat format, double rate) :
|
||||
Track(projDirManager)
|
||||
PlayableTrack(projDirManager)
|
||||
{
|
||||
if (format == (sampleFormat)0)
|
||||
{
|
||||
@ -116,7 +116,7 @@ WaveTrack::WaveTrack(const std::shared_ptr<DirManager> &projDirManager, sampleFo
|
||||
}
|
||||
|
||||
WaveTrack::WaveTrack(const WaveTrack &orig):
|
||||
Track(orig)
|
||||
PlayableTrack(orig)
|
||||
, mpSpectrumSettings(orig.mpSpectrumSettings
|
||||
? std::make_unique<SpectrogramSettings>(*orig.mpSpectrumSettings)
|
||||
: nullptr
|
||||
@ -141,7 +141,7 @@ WaveTrack::WaveTrack(const WaveTrack &orig):
|
||||
// Copy the track metadata but not the contents.
|
||||
void WaveTrack::Init(const WaveTrack &orig)
|
||||
{
|
||||
Track::Init(orig);
|
||||
PlayableTrack::Init(orig);
|
||||
mFormat = orig.mFormat;
|
||||
mRate = orig.mRate;
|
||||
mGain = orig.mGain;
|
||||
@ -171,7 +171,7 @@ void WaveTrack::Merge(const Track &orig)
|
||||
SetWaveformSettings
|
||||
(wt.mpWaveformSettings ? std::make_unique<WaveformSettings>(*wt.mpWaveformSettings) : nullptr);
|
||||
}
|
||||
Track::Merge(orig);
|
||||
PlayableTrack::Merge(orig);
|
||||
}
|
||||
|
||||
WaveTrack::~WaveTrack()
|
||||
@ -1685,12 +1685,8 @@ bool WaveTrack::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
||||
// track is created.
|
||||
mLegacyProjectFileOffset = dblValue;
|
||||
}
|
||||
else if (!wxStrcmp(attr, wxT("mute")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
|
||||
mMute = (nValue != 0);
|
||||
else if (!wxStrcmp(attr, wxT("solo")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
|
||||
mSolo = (nValue != 0);
|
||||
else if (this->PlayableTrack::HandleXMLAttribute(attr, value))
|
||||
{}
|
||||
else if (!wxStrcmp(attr, wxT("height")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
|
||||
mHeight = nValue;
|
||||
@ -1789,8 +1785,7 @@ void WaveTrack::WriteXML(XMLWriter &xmlFile) const
|
||||
xmlFile.WriteAttr(wxT("name"), mName);
|
||||
xmlFile.WriteAttr(wxT("channel"), mChannel);
|
||||
xmlFile.WriteAttr(wxT("linked"), mLinked);
|
||||
xmlFile.WriteAttr(wxT("mute"), mMute);
|
||||
xmlFile.WriteAttr(wxT("solo"), mSolo);
|
||||
this->PlayableTrack::WriteXMLAttributes(xmlFile);
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
int height;
|
||||
if(MONO_PAN)
|
||||
|
@ -69,7 +69,7 @@ class Regions : public std::vector < Region > {};
|
||||
|
||||
class Envelope;
|
||||
|
||||
class AUDACITY_DLL_API WaveTrack final : public Track {
|
||||
class AUDACITY_DLL_API WaveTrack final : public PlayableTrack {
|
||||
|
||||
private:
|
||||
|
||||
|
@ -161,10 +161,12 @@ bool GetProjectInfoCommand::testLinked(const Track * track) const
|
||||
|
||||
bool GetProjectInfoCommand::testSolo(const Track * track) const
|
||||
{
|
||||
return track->GetSolo();
|
||||
auto pt = dynamic_cast<const PlayableTrack *>(track);
|
||||
return pt && pt->GetSolo();
|
||||
}
|
||||
|
||||
bool GetProjectInfoCommand::testMute(const Track * track) const
|
||||
{
|
||||
return track->GetMute();
|
||||
auto pt = dynamic_cast<const PlayableTrack *>(track);
|
||||
return pt && pt->GetMute();
|
||||
}
|
||||
|
@ -127,15 +127,17 @@ bool GetTrackInfoCommand::Apply(CommandExecutionContext context)
|
||||
}
|
||||
else if (mode.IsSameAs(wxT("Solo")))
|
||||
{
|
||||
if (t->GetKind() == Track::Wave)
|
||||
SendBooleanStatus(t->GetSolo());
|
||||
auto pt = dynamic_cast<const PlayableTrack *>(t);
|
||||
if (pt)
|
||||
SendBooleanStatus(pt->GetSolo());
|
||||
else
|
||||
SendBooleanStatus(false);
|
||||
}
|
||||
else if (mode.IsSameAs(wxT("Mute")))
|
||||
{
|
||||
if (t->GetKind() == Track::Wave)
|
||||
SendBooleanStatus(t->GetMute());
|
||||
auto pt = dynamic_cast<const PlayableTrack *>(t);
|
||||
if (pt)
|
||||
SendBooleanStatus(pt->GetMute());
|
||||
else
|
||||
SendBooleanStatus(false);
|
||||
}
|
||||
|
@ -275,13 +275,19 @@ void ExploreMenu( wxMenu * pMenu, int Id, int depth ){
|
||||
size_t lcnt = list.GetCount();
|
||||
wxMenuItem * item;
|
||||
wxString Label;
|
||||
wxString Accel;
|
||||
|
||||
for (size_t lndx = 0; lndx < lcnt; lndx++) {
|
||||
item = list.Item(lndx)->GetData();
|
||||
Label = item->GetItemLabelText();
|
||||
Accel = item->GetItemLabel();
|
||||
if( Accel.Contains("\t") )
|
||||
Accel = Accel.AfterLast('\t');
|
||||
else
|
||||
Accel = "";
|
||||
if( item->IsSeparator() )
|
||||
Label = "----";
|
||||
wxLogDebug("%2i: %s", depth, Label );
|
||||
wxLogDebug("%2i,%s,%s", depth, Label,Accel );
|
||||
if (item->IsSubMenu()) {
|
||||
pMenu = item->GetSubMenu();
|
||||
ExploreMenu( pMenu, item->GetId(), depth+1 );
|
||||
|
@ -98,12 +98,14 @@ void SetProjectInfoCommand::setSelected(Track * trk, bool param) const
|
||||
|
||||
void SetProjectInfoCommand::setSolo(Track * trk, bool param) const
|
||||
{
|
||||
if(trk->GetKind() == Track::Wave)
|
||||
trk->SetSolo(param);
|
||||
auto pt = dynamic_cast<PlayableTrack *>(trk);
|
||||
if (pt)
|
||||
pt->SetSolo(param);
|
||||
}
|
||||
|
||||
void SetProjectInfoCommand::setMute(Track * trk, bool param) const
|
||||
{
|
||||
if(trk->GetKind() == Track::Wave)
|
||||
trk->SetMute(param);
|
||||
auto pt = dynamic_cast<PlayableTrack *>(trk);
|
||||
if (pt)
|
||||
pt->SetMute(param);
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ bool NyquistEffect::Process()
|
||||
mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'DAY-NAME)\n"), now.GetWeekDayName(day).c_str());
|
||||
|
||||
// TODO: Document: Number of open projects
|
||||
mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'PROJECTS)\n"), gAudacityProjects.size());
|
||||
mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'PROJECTS)\n"), (int) gAudacityProjects.size());
|
||||
// TODO: Document. NOTE: unnamed project returns an empty string.
|
||||
mProps += wxString::Format(wxT("(putprop '*PROJECT* \"%s\" 'NAME)\n"), project->GetName().c_str());
|
||||
|
||||
@ -998,7 +998,6 @@ bool NyquistEffect::ProcessOne()
|
||||
cmd += wxString::Format(wxT("(putprop '*SELECTION* (vector %s) 'PEAK)\n"), peakString) :
|
||||
cmd += wxString::Format(wxT("(putprop '*SELECTION* %s 'PEAK)\n"), peakString);
|
||||
|
||||
// TODO: Documen, PEAK-LEVEL is deprecated as of 2.1.3.
|
||||
// TODO: Document, PEAK-LEVEL is nil if NaN or INF.
|
||||
if (!std::isinf(maxPeakLevel) && !std::isnan(maxPeakLevel) && (maxPeakLevel < FLT_MAX)) {
|
||||
cmd += wxString::Format(wxT("(putprop '*SELECTION* (float %s) 'PEAK-LEVEL)\n"),
|
||||
|
@ -425,7 +425,9 @@ bool Exporter::ExamineTracks()
|
||||
|
||||
while (tr) {
|
||||
if (tr->GetKind() == Track::Wave) {
|
||||
if ( (tr->GetSelected() || !mSelectedOnly) && !tr->GetMute() ) { // don't count muted tracks
|
||||
auto wt = static_cast<const WaveTrack *>(tr);
|
||||
if ( (tr->GetSelected() || !mSelectedOnly) &&
|
||||
!wt->GetMute() ) { // don't count muted tracks
|
||||
mNumSelected++;
|
||||
|
||||
if (tr->GetChannel() == Track::LeftChannel) {
|
||||
@ -1255,7 +1257,9 @@ ExportMixerDialog::ExportMixerDialog( const TrackList *tracks, bool selectedOnly
|
||||
|
||||
for( const Track *t = iter.First(); t; t = iter.Next() )
|
||||
{
|
||||
if( t->GetKind() == Track::Wave && ( t->GetSelected() || !selectedOnly ) && !t->GetMute() )
|
||||
auto wt = static_cast<const WaveTrack *>(t);
|
||||
if( t->GetKind() == Track::Wave && ( t->GetSelected() || !selectedOnly ) &&
|
||||
!wt->GetMute() )
|
||||
{
|
||||
numTracks++;
|
||||
const wxString sTrackName = (t->GetName()).Left(20);
|
||||
|
@ -1685,7 +1685,7 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
|
||||
gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT("")));
|
||||
gPrefs->Flush();
|
||||
|
||||
return false;
|
||||
return ProgressResult::Cancelled;
|
||||
}
|
||||
#else
|
||||
if (!exporter.LoadLibrary(parent, MP3Exporter::Maybe)) {
|
||||
|
@ -154,7 +154,8 @@ void ExportMultiple::CountTracksAndLabels()
|
||||
// Count WaveTracks, and for linked pairs, count only the second of the pair.
|
||||
case Track::Wave:
|
||||
{
|
||||
if (!pTrack->GetMute() && !pTrack->GetLinked()) // Don't count muted tracks.
|
||||
auto wt = static_cast<const WaveTrack *>(pTrack);
|
||||
if (!wt->GetMute() && !pTrack->GetLinked()) // Don't count muted tracks.
|
||||
mNumWaveTracks++;
|
||||
break;
|
||||
}
|
||||
@ -811,7 +812,9 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName,
|
||||
for (tr = iter.First(mTracks); tr != NULL; tr = iter.Next()) {
|
||||
|
||||
// Want only non-muted wave tracks.
|
||||
if ((tr->GetKind() != Track::Wave) || tr->GetMute())
|
||||
auto wt = static_cast<const WaveTrack *>(tr);
|
||||
if ((tr->GetKind() != Track::Wave) ||
|
||||
wt->GetMute())
|
||||
continue;
|
||||
|
||||
// Get the times for the track
|
||||
@ -898,7 +901,8 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName,
|
||||
for (tr = iter.First(mTracks); tr != NULL; tr = iter.Next()) {
|
||||
|
||||
// Want only non-muted wave tracks.
|
||||
if ((tr->GetKind() != Track::Wave) || (tr->GetMute() == true)) {
|
||||
auto wt = static_cast<const WaveTrack *>(tr);
|
||||
if ((tr->GetKind() != Track::Wave) || (wt->GetMute())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -175,8 +175,10 @@ void MidiIOPrefs::PopulateOrExchange( ShuttleGui & S ) {
|
||||
|
||||
void MidiIOPrefs::OnHost(wxCommandEvent & e)
|
||||
{
|
||||
wxString itemAtIndex;
|
||||
int index = mHost->GetCurrentSelection();
|
||||
wxString itemAtIndex = mHostNames.Item(index);
|
||||
if (index >= 0 && index < mHostNames.Count())
|
||||
itemAtIndex = mHostNames.Item(index);
|
||||
int nDevices = Pm_CountDevices();
|
||||
|
||||
if (nDevices == 0) {
|
||||
|
@ -224,11 +224,11 @@ void ControlToolBar::RegenerateTooltips()
|
||||
break;
|
||||
case ID_RECORD_BUTTON:
|
||||
commands.push_back(wxT("Record"));
|
||||
#ifndef EXPERIMENTAL_DA
|
||||
#ifdef PREFER_NEW_TRACKS
|
||||
commands.push_back(_("Append Record"));
|
||||
commands.push_back(wxT("RecordAppend"));
|
||||
#else
|
||||
commands.push_back(_("Record Below"));
|
||||
commands.push_back(_("Record New Track"));
|
||||
commands.push_back(wxT("RecordBelow"));
|
||||
#endif
|
||||
break;
|
||||
@ -418,11 +418,7 @@ void ControlToolBar::EnableDisableButtons()
|
||||
if (p) {
|
||||
TrackListIterator iter( p->GetTracks() );
|
||||
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||
if (t->GetKind() == Track::Wave
|
||||
#if defined(USE_MIDI)
|
||||
|| t->GetKind() == Track::Note
|
||||
#endif
|
||||
) {
|
||||
if (dynamic_cast<const AudioTrack*>(t)) {
|
||||
tracks = true;
|
||||
break;
|
||||
}
|
||||
@ -874,7 +870,7 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
|
||||
bool success = false;
|
||||
|
||||
bool shifted = mRecord->WasShiftDown();
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
#ifndef PREFER_NEW_TRACKS
|
||||
shifted = !shifted;
|
||||
#endif
|
||||
|
||||
|
@ -44,9 +44,8 @@ class TipPanel;
|
||||
#define DB_SLIDER 2 // -36...36 dB
|
||||
#define PAN_SLIDER 3 // -1.0...1.0
|
||||
#define SPEED_SLIDER 4 // 0.01 ..3.0
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
|
||||
#define VEL_SLIDER 5 // -50..50
|
||||
#endif
|
||||
|
||||
#define DB_MIN -36.0f
|
||||
#define DB_MAX 36.0f
|
||||
|
@ -351,6 +351,14 @@ KeyView::SetView(ViewByType type)
|
||||
SelectNode(index);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// JKC: Optional code to list commants and shortcuts to debug console.
|
||||
int nLines = mLines.GetCount();
|
||||
for(int i=0;i<nLines;i++){
|
||||
wxLogDebug( "%i,%i,%s,%s", i, mLines[i]->depth, mLines[i]->label, mLines[i]->key );
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,8 @@ Authors:
|
||||
Martyn Shaw
|
||||
|
||||
========================================================================
|
||||
This document is for Audacity version 2.1.2.
|
||||
This document is for Audacity version 2.1.3 and is currently also valid
|
||||
for building 2.2.0-alpha.
|
||||
|
||||
If the advice here is inaccurate or incomplete,
|
||||
email audacity-devel@lists.sourceforge.net.
|
||||
@ -41,7 +42,7 @@ To simplify the implementation of a near-identical user
|
||||
interface across platforms, Audacity uses wxWidgets, a
|
||||
GUI framework.
|
||||
|
||||
Audacity 2.1.2 requires wxWidgets 3.0.2.
|
||||
Audacity 2.1.3 requires wxWidgets 3.0.2.
|
||||
|
||||
To be able to build Audacity for Windows, download and install
|
||||
wxWidgets from http://www.wxwidgets.org/.
|
||||
|
Loading…
x
Reference in New Issue
Block a user