The seed for this idea was sown many years ago when I read about Peter Denny's 'Buckingham Great Central' and in particular about the 'Automatic Crispin'. In summary this was a mechanical automaton that operated the fiddle yard in place of Peter's son Crispin during his absence, hence the name. One of the functions this provided was to ring the appropriate bell code before dispatching or accepting a train. I'd always been taken with the vision of a layout being operated with the gentle tinkle of bells in place of the usual shouting between front panel and fiddle yard operators.
Not quite so many years ago (Ok, quite a few years ago now) I was dismembering an old teletype and one of the components was the bell. This resurrected the bell code concept and added the idea of operating the bell using an old PC. The intention is eventually that the PC will simulate remote boxes ringing local bells and accepting codes beaten in using local tappers, however most things start small and my first step was to present a list of bell code descriptions and get the PC to beep these out using the PC speaker. I've now got around to building a driver circuit for the physical bell which is initially hard coded to be connected to bit 7 of the LPT1 parallel port. For now when the user beats a code using the keyboard the PC speaker is used and when a signalman rings out a code the physical bell is used.
The first version of the software was written using an old PC loaded with DOS. On this I only had available Microsoft Quick C and some libraries for simple text based windows. After an extremely protracted interval lying fallow a recent period of inactivity has allowed me to revisit the code. So far I've shifted it from Quick C to Borland C++ v4.0 and replaced the third party windows library with Borland Turbo Vision (for now I want to stay with the DOS target environment). One other change is the original code used a blocking delay function call. I've recently replaced that with a time out class which invokes a callback when it expires and I've started decomposing it's previously monolithic structure into a number of discrete classes (some tied to the DOS environment and some having 'pure' behaviour).
From the above it should be realised that this code is still in a state of considerable flux and subject to frequent, sometimes violent, change.
The decomposition means the code falls into two major groupings, general 'utility' code and Bellmaster specific code. Within these there are sub groupings for code which is dependant on the TurboVision library, that which is dependant on Borland BC libraries and that which has no dependancies.
There is some documentation courtesy of . All the source code is available in a pair of zip file one for the general utility code and one for the Bellmaster specific code.
There is no user documentation or online help but the program only has a few functions. The one to make a signalman ring out a code is pretty obvious in how to use it. The one to allow a user to beat out a code has a few more twists.
When the user selects to beat out a code a dialog is displayed with two buttons. Select 'Cancel' and the dialog is closed. Select 'Beat' and the bell rings. On the first ring of the bell a signalman is selected to listen to the bell. If only one signalman is loaded then they are selected by default. If more than one signalman is loaded the user is presented with a dialog to select a signalman.
Once selected the signalman listens to the bell. If this doesn't ring for one and a half seconds they will decide the sequence is finished and try to work out what it was. Once this has been determined a dialog is displayed showing the sequence the signalman thinks was rung and listing any descriptions that match that sequence. If the user decides to 'Accept' the sequence the signalman will ring it back out.
One piece of advice. When manually beating a bell code use the space bar rather than the mouse, it's a lot easier to get the timing even.
Bell codes are defined in text files ending with '.bcd'. Each entry consists of two lines. The first line is the descriptive text displayed by the program. The second line is a comma separated list of the number of rings associated with the description. A file contains many such entries and when the file is loaded these replace those currently in use.
Signalmen are described in text files ending with '.sgm'. Each entry consists of three lines. The first line is the name of the signlaman displayed by the program. The second line is the amount of time, in milliseconds, between rings for that signalman. The third line is the amount of time, in milliseconds, the signalman pauses between groups of rings in a sequence. A file contains only one such entry and when the file is loaded this is added to those currently in use, n.b. you can add the same signalman many times!
When the program starts it looks for a default bell code file and a default signalman file in the current working directory. For those who don't wish to build the program here's the current executable.
|Presentation Files (DOS Turbo Vision specific)|
|bellmstr.cpp||Main program file (containing 'main' function).|
|bmapp.cpp, bmapp.h||Source and header file for App class, the Turbo Vision application class.|
|bmcdlvw.cpp, bmcdlvw.h||Source and header file for CodeListView class, a list viewer to display a list of bell code descriptions.|
|bmcdwin.cpp, bmcdwin.h||Source and header file for CodeWindow class, a dialog to display a list of bell code descriptions from which the user can make a selection.|
|bmsgwin.cpp, bmsgwin.h||Source and header file for SignalmanWindow class and nested SignalmanWindow::ListView class, a dialog to display a list of signalmen from which the user can make a selection.|
|bmsplwin.cpp, bmsplwin.h||Source and header file for SplashWin class, a dialog to display the applications 'about' information (displayed briefly on start and on demand from the help menu.|
|bmsqwin.cpp, bmsqwin.h||Source and header file for SequenceWindow class, a dialog to display a sequence and a list of any matching descriptions.|
|bmtprwin.cpp, bmtprwin.h||Source and header file for TapperWindow class, a dialog to allow the user to beat a bell code for recognition by a signalman.|
|lptnote.cpp, lptnote.h||Source and header file for LptNote class, specialises Note to sound bell using PC LPT parallel port (doesn't actually belong in this package so I'll move it eventually).|
|Application Files (BC specific)|
|bcarch.cpp, bcarch.h||Source and header file for BellCodeArchive abstract base class, manages BellCode storage.|
|bcarchst.cpp, bcarchst.h||Source and header file for BellCodeArchiveStream class, specialises BellCodeArchive to store and retrieve BellCode class instance to and from an iostream.|
|bclarch.cpp, bclarch.h||Source and header file for BellCodeListArchive base class, manages BellCodeList storage.|
|bclist.cpp, bclist.h||Source and header file for BellCodeList class.|
|bell.cpp, bell.h||Source and header file for Bell class, a bell is used to ring out a sequence.|
|bellcode.cpp, bellcode.h||Source and header file for BellCode class, holds a unique description and it's associated sequence (this might not be unique).|
|pcbell.cpp, pcbell.h||Source and header file for PcBell class, rings using built in PC sound facilitites (determined by type of Note specialisation used).|
|sgarch.cpp, sgarch.h||Source and header file for SignalmanArchive abstract base class, manages Signalman storage.|
|sgarchst.cpp, sgarchst.h||Source and header file for SignalmanArchiveStream class, specialises SignalmanArchive to store and retrieve Signalman class instance to and from an iostream.|
|sgmlist.cpp, sglist.h||Source and header file for SignalmanList class.|
|sgnlman.cpp, sgnlman.h||Source and header file for Signalman class, a signalman beats out codes using a tapper. Also listens to bells and determines code being rung.|
|tapper.cpp, tapper.h||Source and header file for Tapper class, tapper causes the bell in the signalbox at the other end of the block to ring.|
|Utility Files (DOS Turbo Vision specific)|
|spkrnote.cpp, spkrnote.h||Source and header file for SpeakerNote class, specialises Note to sound using PC speaker.|
|Utility Files (BC specific)|
|cllbklst.cpp, cllbklst.h||Source and header file for CallbackList class.|
|mytrace.cpp, mytrace.h||Source and header file for MyTrace class, a simple trace utility.|
|timeout.cpp, timeout.h||Source and header file for Timeout class, a millisecond resolution time out which invokes a callback on expiration.|
|timer.cpp, timer.h||Source and header file for Timer class, a millisecond resolution timer which provides duration and interval timing.|
|tmoutlst.cpp, tmoutlst.h||Source and header file for TimeoutList class, used to hold and run all current time out instances.|
|Utility Files (generic)|
|callback.h||Header file for callback template classes: CallbackBase; ClassCallback; Callback; ConstCallback; DataCallback; DataConstCallback and InfoCallback.|
|note.h||Header file for Note abstract base class, used by PcBell to output bell sound.|
|watchable.cpp, watchable.cpp||Source and header file for Watchable base classthat supports a list of callbacks to be invoked when a significant change occurs.|
© Monitor Computing Services Limited 2003