Publish audio snippets from WriteLog
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


This is a PHP application that can serve audio snippets from recording contest logging WAV files from contests logged with WriteLog ( Instructions are provided for how to process your WAV files to put on your webserver, and where to put the ADIF files.

Files you must upload to your PHP server

In addition to all the files from this repository, you must also upload these files created by WriteLog from the .wl file:
  • In WriteLog, do a File Save As... and chose ADIF format
  • From WriteLog's AudioRecording directory, you must upload the following files:
    • StartingTimes.txt
    • all the ReceivedAudionnn.WAV files
Here is the directory structure you must create on your PHP server and the files in it (from this repo):
  • index.htm empty file
  • noaudio.wav
  • ReceivedAudio.php
  • wlConfig.php edited as below
  • wlLogReview.php
  • wlQso.ico
  • changeMe make up an obscure directory name and create it in your web server. Upload these data files to that subdirectory:
    • StartingTimes.txt as created by WriteLog in its AudioReview directory.
      For a Linux PHP server the file names are case sensitive. ReceivedAudio001.WAV is not a match to ReceivedAudio001.wav.
    • ReceivedAudionnn.WAV ditto. Note: All the .WAV files named in StartingTimes.txt must be uploaded else none of them will work. If you want to test without all the .WAV files, then edit StartingTimes.txt to refer only to the uploaded ones.
    • <log>.adi as created by WriteLog using File Save As...
The URL for web users to access your server will be:


If you prefer another name to wlLogReview.php, you may change it using mainPageName in wlConfig.php; see below.

Editing wlConfig.php

$myCallSign = "W5XD";           // For displaying on the page.
$adifFileName = "changeMe.adi";   // Name of the ADIF file you put on your PHP server
$maxQsosFromQuery = 100;        // Maximum QSOs it will put on a page of results
$enableEmbedPlayers=false;      // Enables the Show Media Player button on the page
$enableMatchUsingRegularExpression = true; // Advanced feature
$serveLeftAndRightAudioSeparately = true;  // Advanced feature.
$byteRateAdjust = 1.0; // Compressed audio (formats other than PCM) may not report exactly
$secondsBefore = 30;            // Seconds of audio to play before the QSO log time
$secondsAfter = 10;             // Seconds of audio to play after the QSO log time
// Anything you want on the page may be put as HTML in $userHtml
$userHtml = "<p>User HTML goes here</p>";
$mainPageName = "wlLogReview.php"; // change this only if you rename the main page
$subdirectoryName = "changeMe/"; // prevents browser access. put your adi, txt, wav files in a subdirectory 
$debugAudio = false;    // Advanced feature

$myCallSign is how you want your call displayed on the web page.

$adifFileName is the name of the ADIF file containing the log you want to post.

$maxQsosFromQuery is the maximum number of QSOs the page will display in reponse to a query of your ADIF file. If the number of matching QSOs exceeds this, the results page has an added "Skip" form which enables the user to go through the matching QSOs in batches of $maxQsosFromQuery.

$enableEmbedPlayers set to false returns results pages with no embedded media players. Turning this to true adds a "Show Media Players" button to the query form. The embedded media players give a nice visual effect and are convenient, but they have the performance penalty that their mere presence on the page causes the immediate download of all the corresponding audio snippets as a result of the query. If you are browsing a large log with lots of maxQsosFromQuery, then this can be a large bandwidth load.

$enableMatchUsingRegularExpression set to true enables the "Search by RE" button on the query form. This is an advanced feature that allows returning pages with QSOs from many stations, but it uses the mind-numbingly complex UNIX regular expression syntax. With this set to false the query is for just one callsign and only calls that exactly match will be returned (uppercase and lower case all match).

$serveLeftAndRightAudioSeparately is an advanced topic that requires its own discussion. See below.

$byteRateAdjust is normally left at 1.0. Some compressed .WAV files, however, do not report their byte rate exactly in their header, which can cause the audio snippets to be displaced in time for QSOs logged toward the end of a .WAV file. If you did not turn on compression in WriteLog, then you won't need to adjust this (and you will also have .WAV files that are 155MB per hour.) Here is a procedure to set this parameter for the case where you have compressed files:

  • Look at your StartingTimes.txt and choose a .WAV file that is nearly 60 minutes long, judging by the difference between its start and the start of the next .WAV file. Note the start time of the next .WAV file, and then subtract, a short interval, about 5 minutes, to make sure you are looking for a QSO at the end of that .WAV file.
  • Look in your log (or .adi file) for a QSO logged at about that 5 minutes-before-the-end of the .WAV file.
  • Enter that call into your new web page, wlLogReview.php and playback the audio. If you hear the audio for the QSO you looked up, then all is well and you may leave $byteRateAdjust at 1.0
  • If you hear the audio for a QSO before the one you looked up,then $byteRateAdjust needs to be set just higher than 1.0. The value 1.001 will shift the snippet 3.6 seconds later for QSOs logged at the end of a .WAV file.
  • If you hear the audio for a QSO after the one you looked up, then $byteRateAdjust needs to be set just lower than 1.0. The value .999 will shift the snipped 3.6 seconds earlier for QSOs logged at the end of a .WAV file.
$secondsBefore and $secondsAfter set the length of the audio clip returned in the query. These are the offsets, in seconds, from the time of the QSO in the ADIF file. Since contest operation normally results in logging the QSO after the exchange is both sent and received, the $secondsBefore should normally be bigger than $secondsAfter. Negative values are allowed for these, which can be needed to handle the problem of a clock difference when recording audio on a different PC than was used to log the QSOs. Remember in that case that to shift the entire snippet by an offset, you must add the offset to one of these and subtract from the other (for example, to keep the snippet the same length and move it 30 seconds earlier, you must add 30 to $secondsBefore and subtract 30 from $secondsAfter.)

$userHtml you may set to HTML (or plain text if you like) that you want displayed with the query results.

$mainPageName should not be changed unless you have some reason to change the name of the provided wlLogReview.php file. $mainPageName must be the name of the file that used to be wlLogReview.php.

$subdirectoryName must always be changed. Choose some directory name that internet users will not likely guess. If you set $subdirectoryName="", then anyone can download your StartingTimes.txt file, and the ReceivedAudionnn.WAV files in their entirety. And anyone that can guess the name of your ADI file can download your entire log. To prevent this, choose an obscure name for a directory, and place your StartingTimes.txt file, your .adi file, and your .WAV files in that subdirectory.

$debugAudio set to true causes the audio snippet calculations routines to return a formatted html page instead of the audio itself. If your audio snippets do not work and you can't tell why, you might try turning this on and see if the extra diagnostics returned tell you anything helpful. This really is a debugging tool only.

Here is what the screen looks like with all the features turned on. WebLogReviewExample.png

Here is what it looks like with all the features turned off. WebLogReviewExample.png

WAV File Formats

The scripts have only been tested on the original WAV format produced by WriteLog while continuously recording audio to file with WriteLog's compression turned off. However, the PHP code is designed to be general enough to create audio snippets from any .WAV file that adheres to the Microsoft standard for .WAV files. The PCM format files created by WriteLog are uncompressed and quite large compared to what is possible with compression. You may convert WriteLog's .WAV files to a compressed format and give them a try to save disk space on your server.


With this feature set to the default false setting, the audio snippets served from the page are stereo. The user will hear any two-radio operation just as it occurred during the contest. If instead you would rather web users only be able to hear the audio snippet corresponding to the radio used to log the QSO with them, then you may turn this feature to true, but you are not finished setting up your server yet! The PHP scripts provided do not separate the original stereo channels to mono. You have to create separate left and right .WAV yourself with an audio editing tool. Here is the list of things you must do to serve snippets with left and right channels separated:
  • This list is only for the case where you want to separate the stereo files created by WriteLog so that your web log review plays only the left or right channel based on which radio made the QSO.
  • Before the contest, you must setup WriteLog using the "Setup / Log which Radio Makes the QSO". This puts the left/right radio information in the ADIF file. If you didn't do this before the contest, then you may stop now, because none of the rest of this will work without that information from the original log.
  • Create two subdirectories in WriteLog's AudioRecording directory that contains your stereo .WAV files, and the StartingTimes.txt file.
  • Name one of the two subdirectories "Left" and the other subdirectory "Right".
  • Use an audio editing tool (I use goldwave, for example) to read ReceivedAudio001.WAV and write out two files. Write a monophonic file of the left channel to subdirectory "Left" using the same file name, ReceivedAudio001.WAV, and then write the right channel to the same named file in subdirectory "Right".
  • Repeat for all the original ReceivedAudionnn.WAV files in the AudioRecording directory.
  • With $serverLeftAndRightAudioSeparately turned to true, you must provide two separate StartingTimes files. Copy the original StartingTimes.txt file to two separate files: StartingTimes1.txt and StartingTimes2.txt. Edit these files according to the next step. These new files will remain in the AudioRecording directory--not in the L or R subdirectories. The "1" and the "2" correspond to the values in the "r" column that appear in WriteLog's log display window.
  • The QSOs that WriteLog flagged as "1" and "2" will correspond to left or right channels of audio, but which is which depends whether WriteLog was setup its upper Entry Windows as left or right. The upper window is radio "1" and corresponds to StartingTimes1.txt.
  • Edit StartingTimes1.txt by putting "Left/" or "Right/" in front of each file name.
    • Contents of StartingTimes.txt before:
      ReceivedAudio001.WAV 2010-07-21 01:53:11
      ReceivedAudio002.WAV 2010-07-21 01:54:12
      ReceivedAudio003.WAV 2010-07-21 01:55:33
    • After:
      Left/ReceivedAudio001.WAV 2010-07-21 01:53:11
      Left/ReceivedAudio002.WAV 2010-07-21 01:54:12
      Left/ReceivedAudio003.WAV 2010-07-21 01:55:33
  • Edit StartingTimes2.txt similarly, but start with Right/ instead of Left/, or vice versa
  • To summarize, here is what files you have in your directories, and which ones you need to upload to your PHP server.
    • changeMe(obscure subdirectory name on your server)
      • StartingTimes.txt--original as created by WriteLog. Not needed on the server in this configuration.
      • StartingTimes1.txt--edited to indicate whether it is Left or Right--upload to PHP server
      • StartingTimes2.txt-- ditto
      • ReceivedAudio001.WAV--original as created by WriteLog. Not needed on the server in this configuration.
      • ...remaing .WAV files--ditto
      • Left (directory) -- create same named directory on the PHP server
        • ReceivedAudio001.WAV--upload to the PHP server
        • ...remaining .WAV files--upload to the PHP server
      • Right (directory)-- create same named directory on the PHP server
        • ReceivedAudio001.WAV--upload to the PHP server
        • ...remaining .WAV files--ditto
  • To repeat. This list is only for the case of separating the left and right channels from the two radios