Tuesday, June 17, 2014

NVDA: Source code documentation (June 2014)


For some time, I’ve been thinking about writing a book called “NonVisual Developer’s Aid to NVDA,” a comprehensive reference on NVDA’s source code. I sort of wrote an outline for it while I was writing the add-on development guide, but decided to post the actual documentation that comes with the source code in hopes that someone might learn something about NVDA, screen reading technology, accessible software design and perhaps contribute to NVDA (and perhaps write a book about nVDA with the source code docs). If you are a developer wishing to know the internals of NVDA, this is for you (and hats off to Mick Curran and Jamie Teh, who deserves the credits for writing the source code docs and NVDA in the first place).

A zip file is now available containing source code documentation for the latest master branch (June 2014). Note that this should be studied by programmers who are serious about extending NVDA’s core and/or interested in internals of how add-ons work their magic (in reality, anyone is welcome to study it, publish a book based on the source code, etc. (if you do plan to publish a book, I’d advise asking NVDA devs).

But first, for people who are just getting started with NVDA development should read the latest developer guide, which can be found at:


Now for the source code documentation (based on master branch as of June 2014):


For Mick and Jamie, I hope I’m not going against your rules…


An NVDA translator and add-on writer


Station Playlist Studio add-on for NVDA: cart explorer explained


One of the new features in upcoming SPL add-on 3.0 is Cart Explorer, a way to learn cart assignments in SPL Studio. Below is a section from the 3.0-dev add-on guide (not available yet) that explains how cart explorer works:


Cart Explorer

SPL Studio allows you to assign up to 96 carts, or jingle machines. When the cart command is pressed, Studio plays the assigned jingle. You can also edit jingle assignments while cart edit mode is active.

The cart commands are:

* F1 through F12 either by themselves, or in combination with Shift, Control or Alt (e.g. F2, Shift+F11, Control+F5, Alt+F12).

* Number row from 1 through 9, 0, hyphen (-) and equals (=) either by themselves or in combination with Shift, Control or Alt (e.g. 5, Shift+-, Control+=, Alt+0).

Hint: because Alt+F4 is a cart command, press Control+Alt+X to quit SPL Studio.

To help you learn what jingle will play when a given cart key is pressed, NVDA allows you to explore cart assignments. Press Control+NVDA+3 to enter Cart Explorer. When you press the cart key once, NVDA will tell you which jingle is assigned to that cart key. When pressed twice, the jingle associated with the cart command will be played. Once you've explored the cart assignments, press Control+NVDA+3 to leave Cart Explorer.


Let NVDA learn cart assignments

By default, Studio assigns F5 to a jingle called "Kewel". you can teach NVDA the actual cart assignments for each cart key. Follow these steps to let NVDA learn cart assignments:

1. From Start menu/screen, select "Explore NVDA User Configuration Directory".

2. Once the user configuration folder opens, look for a file named "splcarts.ini". If the file doesn't exist, create a text file named "splcarts.ini". Open either the existing or the new file.

3. For each line, write the cart assignments as follows:


where cart is the cart key and jingleName is the name of the jingle you want NVDA to announce when this key is pressed. For example, the default Kewel jingle (assigned to F5) entry would look like:


Enter your cart assignments, then once you're done, save and close the file.

4. Back at SPL Studio, enter Cart Explorer (if you were in cart Explorer, exit then reenter this mode). NVDA will now recognize your cart assignments and will announce them as you press the newly assigned cart keys.

5. To remove a cart from being announced, open splcarts.ini and remove the entries you no longer need. Save the file, reenter Cart Explorer and NVDA will learn that you have removed an entry from list of carts.

Note: If a cart is not assigned (either not assigned from the beginning or removed), NVDA will announce, "not assigned". Also, if splcarts.ini is not present in your user configuration folder, NVDA will tell you of this fact and will not enter cart explorer.

Hint: if you wish to preserve cart assignments (for example, if you have identical jingle sets in SPL Studio running on two or more computers), copy splcarts.ini from your first computer to the second computer (splcarts.ini will be used in version 3.0 or later).


Go to addons.nvda-project.org, select Station Playlist Studio link, then download the development version to try cart explorer (note: don’t use development version in a production environment; for production releases, use stable version, which is 2.x).


P.S. Blog post requested by an add-on tester.

Sunday, June 8, 2014

NVDASR: diary of do's and don'ts in NVDA tickets, add-ons and what not


One of the strengths of software development is ability for users and developers to participate in shaping a software. This is more important if this software is needed by the user (or users) for performing various tasks. But there are times when something comes up that makes programmers sigh and think, “hmmm, maybe I need to tell users how they can help me.” This is one of those posts, and for those who are NVDA (NonVisual Desktop Access) users, you might want to keep this in mind to help NVDA developers in understanding your needs. To address different user groups, I’ ve organized this post into sections so you can quickly jump to the desired section.


Filing issues

Bugs are bound to exist in any software project. Once a user finds a bug, he or she would tell the developer about the bug in hopes of getting it fixed.

For the most part, NVDA developers receive good amount of information about a bug when a user files a ticket (issue). However, there are times when programmers ask the user to provide more details such as version of the app, how to reproduce a problem and so on.

Here are some questions that might be asked when filing an issue with NVDA (or with any software):

·        Steps to reproduce a problem: Sometimes, a user may not write how to reproduce a problem (if it is a recurring one). Just saying “… this problem exists …” or “… NVDA should do this and that …” does not provide the picture the developers need. The first and important information to provide (besides other info such as version of the program you’re using) is the procedure to reproduce a problem. This includes commands you’ve tried, expected behavior, actual behavior and so on.

·        Is this specific to NVDA: a good way to test this is running multiple screen readers, with the user trying the problem steps with each screen reader. If ALL of them produce the same result, chances are that it might be the application that’s causing the issue. If the problem exists when NVDA is used, then the probability of this being an NVDA issue increases.

·        Program version: a problem with one version of a program may not mean the problem exists with other versions (more so in Office applications and web browsers). If possible, please test for the issue with more than one version of the program in hopes of narrowing down the problem to a specific version.

·        Do not paste the entire contents of your log file: if you need to paste a log fragment, try pasting only the relevant log fragment – that is, one minute prior to the start of the problem and up to one minute after, with the log level set to input/output from NVDA’s General Settings dialog.

·        Search the tickets before filing the issue: it is important to remember that a feature that you’re suggesting may have been suggested before, hence searching the ticket system before posting a brand new suggestion.



One of the strengths of NVDA is add-ons, which allows programmers (and users) to extend NVDA’s functionality through Python modules.

Some do’s and don’ts about add-ons include:

·        Learn Python: add-ons are Python code, so it is essential that you know Python and can use it (write some programs in Python first before writing import addonHandler).

·        Get ready to write more English than Python: it may sound odd to say this, but throughout the life of your add-on, you’ll be talking with users, so be prepared to explain what you’re doing.

·        Get intimate with your target system: no, not love. I’m talking about being familiar with the app you’re writing the app module for, feature for which you’ll be writing your next global plug-in, and features of your speech synthesizer and braille display you wish NVDA users to use.

·        Invite your users along the ride: it is important to remember that your “passengers” (clients) are users who uses a particular app, a feature in NVDA, etc. Invite them along, listen to their suggestions, go through steps to reproduce bugs and what not.

·        Don’t use fancy routine unless if you know what you’re doing: it is better to keep the code simple and make it run instead of using fancy functions and break your add-on. If you want to make your add-on work faster, don’t do it until the very end (I might add, “don’t try it”) after you know for sure your add-on works as advertised i.e. works 100%.

·        Make a habit of visiting NVDA’s Python Console: test your routine in the console (especially if writing a routine in an app module) before writing your code in the add-on file.

·        Always debug with multiple scenarios: your add-on may only work for certain app versions, or your synthesizer may not pronounce things right. Always debug your add-ons with multiple scenarios (different versions of an app, different braille display models, etc.).

·        Most importantly, have fun.

That’s all for tonight. Hope this helps.

Dynamic programming algorithms: try Pass Triangle from Code Eval


A close friend of mine sent a tweet a few days ago announcing:

I have solved some challenge at Code Eval…

Since I was preparing for my algorithms final, I decided to give Code Eval a try to review various algorithms I’ve learned in class.

How it works: Code Eval (www.codeeval.com) let’s you submit solutions to various challenges in your favorite language (for me, C++ and Python). Once you submit your solution, it’ll score your output, and if you solve it, gives you an opportunity to tweet about it. The aim of the site is to connect programmers and companies, as part of this purpose, Code Eval lists “package problems” where a company sponsors a challenge (some are easy, others are hard).

Now why do I mention the Pass Triangle challenge from Code Eval? Because it helped me understand what dynamic programming algorithms are and how they work. Dynamic programming allows building the solution to a problem by computing answers to subproblems. This is done by filling out a table based on a defined pattern, or it is called “recurrence relation.” Effectively, when you’re solving problems involving dynamic programming, you’re solving this recurrence relation.

The pass triangle challenge can be found at:


Here, one would be tempted to start with greedy choice, since you can add sums for each level and choose the maximum of two subtrees. But this will not work, hence dynamic programming is the way to go (you would fill out a solutions table, then choose the max once you’re done with the entire tree of numbers).

Good luck.


NVDA Add-ons 2: types of add-ons


Let’s continue with add-on development…

Last time, we talked about preparing for add-on development. We left off at what kinds of add-ons are available. Let’s go over types of add-ons available.

Add-ons can be divided into three categories: global plug-ins, app modules and drivers. A global plug-in adds additional functionality for NVDA, such as OCR capability, support for controls seen in multiple apps and so on. Examples are OCR, emoticon announcements and so on. In contrast, an app module provides support for an app, with examples being GoldWave, Outlook and so forth. Lastly, drivers provide support for speech synthesizers and braille displays.

Each add-on type inherits from a base module. A typical initial code looks like this:

import globalPluginHandler/appModuleHandler/handlers for drivers

Then you would write:

Class AppModule(appModuleHandler.AppModule)/GlobalPlugin(globalPluginHandler.GlobalPlugin):


I will not cover drivers here as they require extensive knowledge of how synthesizers/braille displays work (and I haven’t written any). We’ll start with similarities between global plugin and app modules, and we’ll dive into differences between them.


Reopening the blog after a year...

Hi all,

Welcome back to Musings of a Blind Highlander. It’s been a year since I posted about my life and other topics. Now that I’m learning about few advanced things, I’d like to take some time to share it with you.

So what was I doing for the past few months? I’ve been continuing with my computer science degree, wrote some NVDA code and what not. I hope to continue with NVDA add-ons series and continue with CS topics.