Problem Description
How would you write a program the plays a specified
MP3 audio file when a sentence in a TRichEdit rich edit control is clicked?
Here's a little program that answers that question.
Background & Techniques
A program like this might be good for letting a reader learning a foreign
language hear the pronunciation by a native speaker, for example. MP3
files are generally more compact than .Wav files with the same content, so might be a
good choice.
Using my usual "Divide and Conquer" technique of problem solving, I
divided the job into 4 smaller problems.
- Identifying a clicked location. in the text.
- Identifying the position range of each sentence in the text so a
clicked location can be associated with a sentence.
- Associating a specific MP3 file with each sentence..
- Playing the MP3 files.
For the 1st problem, there is no specific OnClick event exit but
either the
OnMouseDown
or
OnMouseUp
exits will do, I chose OnMouseUp. Edit controls like rich edits identify the
selected text with SelStart and SelLength properties.
SelStart is the character position within the entire rich edit text where a mouse button was pressed and
SelStart + SelLength is the character position where the mouse button was
released. For a normal mouse "click", SelLength will
be 0 because the mouse down and mouse up positions are the same.
For the 2nd problem, associating the clicked position with a sentence we
can look at two sub problems. Problem 2A, for we need to
count the sentences and identify the character position within the text
where they start and end. Scanning and building a table based on
sentence ending periods should do that. (This program doesn't handle
cases where text contains numbers with embedded decimal points or
abbreviations with periods, we'll leave that problem for version 2
J.) Once we have the clicked position from
step one, just need to find which of the sentence ranges contains that
clicked position value (problem 2B). Since we can assume that each
sentence begins one position after the previous sentence ends, all we need to
retain in a table is the end positions. The clicked sentence is then
the first end position that is greater than or equal to the clicked
position. For example, if three sentences ended
at character positions 100, 200, and 300, a click on position 150
would belong to sentence #2.
Problems 3 is solved simply by making a list of file names to be played
for each sentence. It is probably best to make the list complete so
that every click plays something. In that case, then sentence number
is simply an index into a string list or array of MP3 file names.
Clicking on the 4th sentence lays the 4th MP3 file, etc.
On to problem 4, actually playing the file. My first attempt was to use the ShellExecute API call to open the file. This
automatically starts the program , associated with that file. For
Windows, that normally is Windows Media Player (WMP) and the problem
is that it opens in whatever default mode is configured. We really
don't need a full blown animated skin WMP opening each time we play a file.
Changing ShellExecute to open WMP.exe directly and passing the file name
as a parameter and using the SW_HIDE parameter, works much better.
If a program using this technique were to be distributed, it would probably
be necessary to have name of the MP3 player to be executed set in a
parameter file that the user could change for their system.
Running/Exploring the Program
Suggestions for Further Explorations
????
|
Original Date: November 24, 2008 |
Modified:
November 25, 2008 |
|