Play MP3 Files

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math Topics]   [Library]   [Utilities]

 

Search

 

Search DelphiForFun.org only

Support DFF

 If you shop at Amazon anyway,  consider using this link. We receive a few cents from each purchase.   Thanks.

In Association with Amazon.com

 

Support DFF

 If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

 

 

Contact

Feedback:  Send an e-mail with your comments about this program (or anything else).

 

Search DelphiForFun.org only

 

 

 

 

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.

  1. Identifying  a clicked location. in the text.
  2. Identifying the position range of each sentence in the text so a clicked location can be associated with a sentence.
  3. Associating a specific MP3 file with each sentence..
  4. 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.  

Addendum September 30, 2010: Here's Version 2 which turned out to be a fairly major rewrite of the original.  The sentence start and end positions within the text are no longer significant.   A young lady wrote asking how to to respond to a user click on a sentence by playing an MP3 or WAV file identified by text which is enclosed in parentheses within the sentence.    The file identification text is to be highlighted while the file plays. Clicks are ignored for sentences with invalid or missing file identification text.  For text that might require future maintenance, tying the file to such special text would be more practical than tying the file to a character position range as implemented in the original version. 

In this version, a setup page allows the user to maintain the default text and to load other text files for testing. She may also save, load, and maintain a "File Association" table which connects the file identification text with the actual audio file names. Each line of the File Association table has the format "FileId=Filename" . "FileId" is the text string which appears within the last set of parentheses in the sentence to trigger the playback. "Filename" is the name of the file to play.

The code to trigger audio playback performs these tasks:

  1.  Recognize the user click. A RichEdit OnMouseUp event exit performs the search.
  2. The SelStart property identifies the location within the text where the click occurred.
  3. Uses PosEx function to find the period at the end of the sentence.
  4. Scans back character by character looking for a ) character. If found scan, back from there to the open paren ( and copy the enclosed text to a TagId string.
  5. We use the Name=Value string list facility to look for the TagId as a Name field and verify that the Value field is the name of an existing file.
  6. If we have a valid filename, use the RichEdit  SelAttributes property to highlight the TagId text, play Filename file using a TMediaPlayer control, and then reset the text attributes back to the DefAttribute values.

I'll retain links to both the original and the revised version downloads for future reference.

    

Running/Exploring the Program 

bullet Download Version 1 source
bullet Download Version1  executable
bullet Download Version 2 source
bullet Download Version 2 executable

Suggestions for Further Explorations

In Version 2, an additional setup option could allow the highlight color or text style to be modified. 

 

Original Date:  November 24, 2008 

Modified: September 30, 2010

 

  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright 2000-2013, Gary Darby    All rights reserved.