# version 26.7.19

* Fixed installation from NVDA's `.pendingInstall` context: `_ibmttsUtils` now supports both its normal package-relative translation import and the top-level import used by `installTasks`. The suite now contains 44 tests.
* Made every global-plugin UI module load this add-on's own locale catalog explicitly using NVDA's effective language. This prevents another installed IBM add-on with the same `globalPlugins.ibmtts` and `synthDrivers._ibmeci` extension-module names from causing English fallback.
* Kept all source strings in English and all Spanish text exclusively in `locale/es`. Added a regression check for explicit catalog binding; the suite now contains 43 tests.

# version 26.9.4

* Regenerated the POT from the complete current source and synchronized the Spanish PO against it. All 232 active messages are translated, with no empty or fuzzy entries.
* Made 30 previously hard-coded engine, dictionary and isolated-renderer errors localizable and supplied their Spanish translations.
* Added compiled-catalog and full POT-to-PO coverage checks; the suite now contains 42 tests.

# version 26.9.3

* Added complete Spanish localization for the WAV recorder and isolated custom-voice test: dialog titles, fields, voice choices, file filters, buttons, progress, cancellation, playback states and errors. The Spanish catalog contains 205 translated messages (100%), with three compiled-catalog regression checks; the suite now contains 40 tests.

# version 26.9.2

* Fixed startup on frozen NVDA distributions which do not bundle Python's `secrets` module. Private ECI instance identifiers now use the always-available `os.urandom`, allowing both the synthesizer and settings panel to load. A regression test covers reserved identifier regeneration; the suite now contains 37 tests.

# version 26.9.1

* Moved the three long-document lifecycle messages from INFO to DEBUG. Successful reading of very large files no longer adds routine queue, start and completion entries to NVDA's normal log.

# version 26.9.0

* Added a test button for custom-voice edits. It renders the unsaved controls through a private ECI host and handle, leaving NVDA's active synthesizer untouched.
* Added an accessible WAV recorder with typed-text and file input, active/base/custom voice choices, output selection, preview, progress and cancellation. Rendering and playback are independent from NVDA speech.
* Added per-instance pipe, callback-memory and host lifecycle support to the 64-bit bridge, including cleanup after partial startup failures.
* Added conservative duplicate-backlog coalescing after application freezes. It activates only with eight or more queued jobs and preserves the first two identical announcements.
* Added regression tests for private IPC names and pathological backlog detection. The suite now contains 36 tests.

# version 26.8.9

* Restored immediate ECI index delivery when audio is queued. The previous `WavePlayer.onDone` delivery could lose an index when focus changes canceled an audio block, leaving NVDA's speech manager unable to send subsequent tab, control, grouping, or selection speech even though it appeared in Speech Viewer.
* Added integration tests for audio/index/end dispatch order, silent completions, and nonfinal audio blocks.

# version 26.8.8

* Fully restored the original driver's end-marker and completion-callback mechanism for compatibility with NVDA focus speech. The unique-marker and generation-filtered completion experiment introduced in 26.8.4–26.8.6 has been removed.
* Long-document preprocessing remains isolated from the legacy-compatible short-speech and callback core.

# version 26.8.7

* Restored the original IBMTTS execution path for ordinary NVDA interface speech: synchronous dictionary barrier, immediate text processing, embedded character-mode tags, and speech-parameter tags enabled by default.
* The worker-thread pipeline is now restricted to utterances over 3,200 characters. This retains long-document protection without changing the timing of Explorer, settings tabs, controls, or other short focus announcements.

# version 26.8.6

* Replaced the shared ECI end index with unique internal markers. A late callback from canceled window-title speech can no longer consume the completion identity of a newer Explorer focus announcement and leave NVDA permanently waiting.
* Reserved ECI indexes 61440 through 65535 for internal completion markers and added regression coverage for uniqueness, cancellation, and range isolation.

# version 26.8.5

* Long utterances canceled by a transient NVDA focus change before ECI begins processing are no longer discarded. Immediate interruption remains active once processing has actually started.
* Added concise INFO diagnostics for speech over 3,200 characters, recording queueing, worker start, dispatch completion, and whether it was aborted. This distinguishes NVDA/editor freezes from ECI processing without logging spoken content.

# version 26.8.4

* Fixed a cancellation race where a late end-of-speech callback could make the global marker count negative. The next Explorer focus utterance would then never notify NVDA that it had completed, preventing the remaining object details from being spoken.
* End markers now carry their utterance generation. Canceled callbacks are ignored without consuming markers belonging to newer speech, and cancellation clears stale indexes and marker state.

# version 26.8.3

* Fixed startup when an older NVDA profile contains the legacy Boolean value `numberMode=False`.
* Added safe migration and range validation for persisted sample-rate, pause, four-digit-number, and spelling modes. Invalid values now fall back to their declared defaults instead of preventing the synthesizer from loading.

# version 26.8.2

* Preserve short queued NVDA interface announcements across rapid focus transitions. Cancellation generations now discard only long, interruptible document speech, fixing missing Explorer group and selection announcements introduced in 26.8.1.

# version 26.8.1

* Removed the synchronous ECI parameter wait from every speech request, preventing it from freezing NVDA's main thread.
* Moved regular-expression processing and encoding of long documents to bounded jobs on the ECI worker thread.
* Cancellation now invalidates all older queued jobs immediately, so new focus and Explorer selection announcements are not trapped behind stale document speech.
* Fixed the false error reported at shutdown when the ECI thread had terminated successfully.
* Changed adjacent-string coalescing to linear-time joining and added cancellation and shutdown regression tests.

# version 26.8.0

* Reorganized the IBMTTS settings category into General, Library, Dictionaries, Custom voices, and Tools and diagnostics tabs.
* Added a capability-negotiation protocol. Optional ECI functions no longer prevent libraries that do not export them from loading.
* Added an accessible IBM dictionary manager with pagination, exact lookup, add, edit, delete, import, and export operations.
* Added persistent custom voices using ECI user slots 9 through 16, including names and all eight voice parameters.
* Added four-digit number and spelling modes to NVDA Voice settings.
* Added safe English IPA to IBM SPR pronunciation support with text fallback for unsupported input.
* Added library diagnostics, active-voice testing, and manual engine-state recovery tools.
* Added `eciSpeaking`, `eciGetIndex`, `eciReset`, voice-name, dictionary enumeration/editing, dictionary save, and test-phrase functions to the 32-bit bridge as optional capabilities.
* Cancellation now clears pending manual input and restores the tracked active-voice parameters, as required by the ECI API after `eciStop`.

# version 26.7.1

* Fixed startup on existing installations: newly introduced general-profile settings are now initialized from their declared ConfigObj defaults before they are read.
* Added a regression test for migrating an older configuration without `ratesByVoice`.

# version 26.7.0 (SuperAddon audit build)

* Reworked the 64-to-32-bit bridge so each NVDA process uses its own pipe, mutex, shared memory, and events. Multiple signed-in Windows users and multiple NVDA processes no longer share a fragile global host.
* Serialized IPC calls and strictly validated packets and responses, preventing crossed replies and index corruption.
* Added bounded waits and shutdown paths throughout the ECI, callback, IPC, and host lifecycle so a failed engine cannot block NVDA indefinitely.
* Added native `eciPause` support while retaining NVDA audio-player pause support.
* Split very long text before regular-expression processing and before ECI submission, on safe word and multibyte-character boundaries.
* Deliver speech indexes only after the associated WASAPI audio buffer has played, improving callback-command ordering.
* Recover automatically from invalid or stale configured voice identifiers, including `4294967295`.
* Persist variant-derived voice parameters and speech rates per language without overwriting customized settings during configuration loading.
* Use the current NVDA audio device through the current WASAPI `WavePlayer` contract.
* Automatic update checks no longer open a focus-stealing confirmation dialog. Manual checks retain the review dialog with a safe default focus.
* Replaced executable pickle update state with atomic JSON state files.
* Ask the user whether to restart NVDA after changing or copying synthesis libraries.
* Removed unsafe configuration `eval`, hardened PE inspection, file handling, and host response parsing, and corrected several language-condition errors.
* Added a reproducible Rust bridge source tree, a prebuilt 32-bit bridge DLL, static analysis, and regression tests.

# version 26.6.2

Version 26.6.1 introduced a big issue when solving #148. In some cases, The antivirus detected the bridge as a false positive because the intermediary process between 64 and 32 bits tried to remain active during the shutdown processes, until NVDA was closed, and not before.

# version 26.6.1

* FIX: Corrected relative path logic in os.walk to prevent crashes when copying subfolders.
* Remove the creation of the 'eciLibraries' add-on; it is no longer needed since the update process of IBMTTS properly preserves these files.
* Update file copy destination to the 'ibmtts' folder inside 'synthDrivers' of the add-on. 
* i18n: Updated translation template.
* updated Spanish strings.
* Fixed #154: When the issue #147 was fixed, it introduced a new bug, that don't allow the driver to run on  NVDA if the driver has not been run before. The cause is, the 'ibmeci' key does not exist in that situation.
It's a serious problem, so the release was launched quickly. If you're runing IBMTTS, won't be affected, This only happens when IBMTTS has not run before.

# version 26.5.1
* Fixed #147: handle invalid IBMTTS language settings in NVDA: Some IBMTTS configurations may contain an invalid IBMTTS language value, causing the engine to fail to load. This change adds `check_lang_param()` to validate the configured language and apply a fallback when needed:
  1. Use the default language matching the user's locale.
  2. If unavailable, use english, and if unavailable, use the first available language in avLangs.
* Avoid invalid INI paths for those libs using a eci.ini file:
Previously, the INI file was updated only when the configured path was relative. However, some eci.ini files may contain an incorrect absolute path. This change also validates absolute paths and updates them when necessary.
If NVDA cannot write to the INI file, the path cannot be corrected and the IBMTTS synth may fail to work.
* fixed 148: avoid to close the 32 bits process if it's already closed when NVDA is closing the synth. E.G. When the computer is shuting down.
* Restored support for NVDA 2019.3. This fixes issue #151.
* Updated Turkish translations.
* Simplified German anticrash expression, removing the second one for macro, fixing macro - enabled by folding it into the existing expression for audio and video. Fixes #144.

# version 26.4.1

* Implemented 64-bit support while ensuring full backward compatibility with 32-bit systems. This is implemented via a 32-bit DLL host integrated with a 64-bit Python-based proxy DLL. Named pipes were used for calling functions, and shared memory between processes for the audio stream.
* Support for etidev.dll in 64 bits: Now it supports those IBMTTS libs that require etidev.dll. For this, the new IPC endpoint was added, with the ID 242. That id will tell to the host to load etidev.dll lib.
* Fixed issues that occurred when the ECI thread died, improving exception handling. As a result, the driver will no longer block the NVDA session if something fails in the eci lib or the host, and NVDA will be able to switch to another TTS.
* Added some checks in case the tts thread dies. Now the driver will catch more errors in the background thread, allowing NVDA to detect that and change to another voice engine.
* implemented the function to change to another tts if IBMTTS fails.
* fix issue #109: In Spanish, when IBMTTS encounters two or more consecutive numbers where the second one has three digits, it incorrectly reads them as a single large number. This is now fixed by inserting two spaces between the first and second number groups to force a separation.
* fix issue #127: Restore best-fit symbol mapping for IBMTTS: The change from 'mbcs' to 'cp1252' in version 25.2.1 broke certain character replacements. This fix ensures that some symbols outside ansi (such as "Đđ") are properly transliterated when using CP1252.
* Updated french translations, thanks to Michel Such.
* added error handling for the host bridge in 64 bits.
* Fixed #137 when reinstalling the add-on in NVDA 2025 or less. Importing Mmap in _ibmttsUtils was causing issues when it-s imported in installTasks.py. so I moved that import to the function that requires it only. Seems that NVDA tries to get the attrib __file__ in a C module like mmap.
* Added a new dialog to show new changes when updating the add-on

# version 25.2.1

* Temporary fix for an issue with translations when the add-on starts the first time that is installed.
* updated portuguese translations.
* Changed the default encoding. from mbs to cp1252.

# Version 25.1.1

* Added support for NVDA 2025.1.
* Now the driver looks for the audio output in two config paths.
* Deleted the audio output change handler. This was created because in some cases the driver was not synchronized with the current audio output, it needs more testing but seems that this doesn't happen in wasapi mode.

# Version 23.12.1

* Updated support for NVDA 2024.2.
* added some strings that were not translatable.
* Added an option to donate to this add-on.
* Updated installTasks to request for donations during installation.
* Updated locale strings template for translators.
* Updated spanish locale strings.
* Updated documentation to add description of new pause options
* Python 3.11 compatibility (#105)
* Replaced the boolean shorten pauses setting with an expanded setting that allows to shorten no pauses, pauses at utterance boundaries, or all punctuated pauses. (#101): To implement this, the shortPause driver setting has been replaced with a choice setting called pauseMode, using logic based on that used for sample rate selection. This introduces a third pause mode, herein called utterance boundary, that will only reduce the pause at the end of a speech sequence. This has the value 1. The value 2 corresponds to the previous shorten pauses setting set to true, causing the utterance boundary to be shortened as well as the pause-related regular expressions to be applied. This does not presently load the previous shorten pauses setting and adapt to this new scheme, and the string for the utterance mode could likely do with some revision.
* avoid importing add-on modules on installTasks.py, this should fix #85.
* now the availability of the libraries should be detected properly during add-on installation.
* solved compatibility issues with NVDA Alpha V28351 and above. It closes #92, closes #93 and closes #95.
* updated the installTasks to avoid delete internal libraries inside synthDrivers/ibmtts when reinstalling the add-on.
* Added another set of expressions to reduce the verbosity of IBMTTS

# version 23.4.1

* Changed eciSynthMode from the default 0 (Sentence) to 1 (Manual): Synthesis and input clearing is controlled by commands only.
* Tried to work around situations where IBMTTS would say 'comma hundred' or other weird things in English if numbers are separated by commas
* Some fixes in english_ibm_fixes should've actually applied globally. Moved the punctuation fixes formerly part of english_ibm_fixes to a new global_ibm_fixes section to improve the experience for non-English languages
* Fixed short pauses pronouncing the right parenthesis if IBMTTS was used. While this change will make the short pauses expression slightly less affective, it will still work in general
* Updated German anticrash further to catch more cases. #88
* More space removal changes. The expression will take into account numbers as well as letters in the negative lookahead, and added the question mark to its captured punctuation
* Improved the IBMTTS space removal expression so it doesn't catch false positives such as it's a .mp3 file
* added a log message if the selected library is not correct. It shows the exception that raised the failure.

# Version 18-06-2018:

* unused imported modules were deleted.
* fixed crashing expression for spanish language.
* added utf-8 coding header in order to fix some reg expressions.

# Version 13-07-2018:

* changed  pauses from p0 to p1.
* all french fixes were placed in the same conditional.
* now uses x in (1, 2) instead of x==1 or x==2 for all cases.
* added "!" to punctuation list.

# Version 15-07-2018:

* added "-" to punctuation list.
* added pauses for dash "-" symbol.
* comma "," is replaced by dash "-" at the end of a string because eloquence seems to ignore commas at the end.
* deleted "should_pause=False" parameter in xspeaktext because it isn't used anywere in the code. It was used to fix audio issues but currently seems to be unused.
* incorrect behavior when spelling text has been fixed.
* xspeakText changed to processText to clarify code.

# Version 12-08-2018:

* maxRate changed from 250 to 156.
* added rateBoost setting. Enable this option to increase rate by 1.6x.

# Version 16-09-2018:

* Fixed rate param conversion when rate boost is active.
16/03/2019
* Deleted Queue import in ibmeci.py, since this module is not used here.
* Updated code for compatibility with python 3.
* Defined unicode function for backward compatibility with python 2.7.
* added b prefix to strings to treat them as byteStrings, since python 3 strings are unicode by default.
* CHANGED isinstance(item,basestring) TO STR.
* Updated auto language detection to simplify the code and compatibility for python 3.
* Updated processText function.
* Now in _imbesi uses io.BytesIO rater than cStringIo.StringIO
* added seek(0) since BytesIO doesn't update it automatically when truncate.
