Creating dynamic audio files with PHP

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
skehoe
Forum Commoner
Posts: 59
Joined: Sun Dec 22, 2002 5:57 am
Location: Denver

Creating dynamic audio files with PHP

Post by skehoe »

Hey all,

I'm working on a ascii <-> morse code conversion tool and I'd like to add some audio out capability to it (simple dots and dashes at variable WPM rates). I've seen this done on the perl side, but can't find any audio classes for PHP.

Does anyone know where I can find PHP audio classes or have any pointers on how to do this?

Thanks in advance for any help,

~Scott
User avatar
mydimension
Moderator
Posts: 531
Joined: Tue Apr 23, 2002 6:00 pm
Location: Lowell, MA USA
Contact:

Post by mydimension »

you might have more luck looking for a module rather than a class to do this seeing as how this funtionality requires a ton of binary handling and frankly php doesn't excel at binary handling (at least not in my experience).
User avatar
skehoe
Forum Commoner
Posts: 59
Joined: Sun Dec 22, 2002 5:57 am
Location: Denver

Post by skehoe »

Thanks for the feedback. You seem to be the only one that wanted to touch that one. :)

I've seen this done with pack() / unpack() on perl, but I just don't understand the format of the sound files (au, aiff, etc) well enough to do this and unfortunately I don't know perl well enough to work with the example... I'll keep looking and I'll be sure to post back here if I find anything.

~Scott
User avatar
mydimension
Moderator
Posts: 531
Joined: Tue Apr 23, 2002 6:00 pm
Location: Lowell, MA USA
Contact:

Post by mydimension »

here is a site that may help you with the file formats: http://www.wotsit.org/
i ran across it a while ago will doing some VB programming. forget what i was looking for but it has stayed in by bookmarks ever since. now i pass it on to you.
fractalvibes
Forum Contributor
Posts: 335
Joined: Thu Sep 26, 2002 6:14 pm
Location: Waco, Texas

Creating dynamic audio files with PHP

Post by fractalvibes »

Here is site that may not directly be a help:
http://lame.sourceforge.net/

But I'll bet you might can get some direction there.

You might be better off having some pre-recorded sounds - a dot and a dash for instance,as Windows Media clips, for example, and invoking these
as needed - see : http://www.txfb.org/AgClass/resource/AITCrg4.asp
and view source as an idea.

Yet another idea is to look here : http://reglos.de/musinum/InternetMusic.html

I see the site is in transition now - but bookmark that - lots of fun and perhaps another idea. He is using Java to interactively create a MIDI file,
perhaps a best solution, as MIDI is quite small - liken MIDI to a Vector Graphics language for music when comparing with Audio...

Phil J.
User avatar
skehoe
Forum Commoner
Posts: 59
Joined: Sun Dec 22, 2002 5:57 am
Location: Denver

Post by skehoe »

Thanks for the suggestions!

This has been an interesting challenge and everything helps. I'll be sure to update this thread if I ever get anything working.

~Scott
User avatar
skehoe
Forum Commoner
Posts: 59
Joined: Sun Dec 22, 2002 5:57 am
Location: Denver

Post by skehoe »

I got it to work. With PHP. :D

If anyone is interested in the code, PM me and I'll send it to you.

Once again, thanks for all the suggestions.

~Scott
User avatar
llimllib
Moderator
Posts: 466
Joined: Mon Jul 01, 2002 2:19 pm
Location: Baltimore, MD

Post by llimllib »

I'm interested...why don't you just post the code here so anyone reading the forums can see it?
User avatar
skehoe
Forum Commoner
Posts: 59
Joined: Sun Dec 22, 2002 5:57 am
Location: Denver

Post by skehoe »

...Wasn't sure if anyone would be interested.

It's not pretty and not optimized (haven't had any more time to hack on it since early this AM when I got it to work), but it works. :)

Note: you should create a directory 'temp' in the same directory you run it from that has full rw access.

~Scott

Code: Select all

<?

// morse.php
// skehoe - 1.11.03

$morse = array(
	'0'	=>	'-----',
	'1'	=>	'.----',
	'2'	=>	'..---',
	'3'	=>	'...--',
	'4'	=>	'....-',
	'5'	=>	'.....',
	'6'	=>	'-....',
	'7'	=>	'--...',
	'8'	=>	'---..',
	'9'	=>	'----.',
	'A'	=>	'.-',
	'B'	=> 	'-...',
	'C'	=>	'-.-.',
	'D'	=>	'-..',
	'E'	=>	'.',
	'F'	=>	'..-.',
	'G'	=>	'--.',
	'H'	=>	'....',
	'I'	=>	'..',
	'J'	=>	'.---',
	'K'	=>	'-.-',
	'L'	=>	'.-..',
	'M'	=>	'--',
	'N'	=>	'-.',
	'O'	=>	'---',
	'P'	=>	'.--.',
	'Q'	=>	'--.-',
	'R'	=>	'.-.',
	'S'	=>	'...',
	'T'	=>	'-',
	'U'	=>	'..-',
	'V'	=>	'...-',
	'W'	=>	'.--',
	'X'	=>	'-..-',
	'Y'	=>	'-.--',
	'Z'	=>	'--..',
	'PERIOD'	=>	'.-.-.-',
	'COMMA'		=>	'--..--',
	'COLON'		=>	'---...',
	'QUESTION'	=>	'..--..',
	'APOS'		=>	'.----.',
	'HYPHEN'	=>	'-....-',
	'PAREN'		=>	'-.--.-',
	'QUOTE'		=>	'.-..-.',
	'SLASH'		=>	'-..-.',
	'SEMI'		=>	'-.-.-',
	'UNDER'		=>	'..--.-',
	'SPACE'		=>	'/'
);

function create_sound($in) {
    $length = array(
        'dash'      =>  3,
        'pause1'    =>  1,
        'pause2'    =>  3,
        'pause3'    =>  7,
        'word'      =>  50,
        'dot'       =>  1000 * 60 / ($in[wpm] * 50)          
    );

    $pieces = preg_split('//', $in

Code: Select all

);

    $count[dot] = 0;
    $count[dash] = 0;    
    $count[space] = 0;
    $count[slash] = 0;

    foreach ($pieces as $key => $val) {
        if ($val == '.') {
            $count[dot]++;
        } else if ($val == '-') {
            $count[dash]++;
        } else if ($val == ' ') {   
            $count[space]++;
        } else if ($val == '/') {
            $count[slash]++;
        }
    }

    // Sound Header
    $bytes = $length[dot] * 8 * ($count[dot] * (1 + $length[pause1])
             + $count[dash] * ($length[dash] + $length[pause1])
             + $count[space] * ($length[pause2] - $length[pause1])
             + $count[slash] * ($length[pause3] - $length[pause1]));
   
    $sound .= pack(H8,"2e736e64"); // magic number
    $sound .= pack(H8,"0000001c"); // data location (=28)
    $b1 = ($bytes & (255 << 24)) >> 24;
    $b2 = ($bytes & (255 << 16)) >> 16;
    $b3 = ($bytes & (255 << 8)) >> 8;
    $b4 = $bytes & (255);
    $sound .= pack(C4,$b1,$b2,$b3,$b4);
    $sound .= pack(H8,"00000002"); // sound type - 8bit linear
    $sound .= pack(H8,"00001f40"); // sampling rate
    $sound .= pack(H8,"00000001"); // channel count
    $sound .= pack(H8,"00000000"); // optional info (minimum 4 bytes)

    foreach ($pieces as $key => $val) {
        if ($val == '.') {
            $sound .= sound_data(1,1,$length);
            $sound .= sound_data($length[pause1],0,$length);
        } else if ($val == '-') {
            $sound .= sound_data($length[dash],1,$length);
            $sound .= sound_data($length[pause1],0,$length);
        } else if ($val == ' ') {
            $sound .= sound_data($length[pause2] - $length[pause1],0,$length);
        } else if ($val == '/') {
            $sound .= sound_data($length[pause3] - $length[pause1],0,$length);
        }
    }
	return $sound;
}

function sound_data($units,$onoff,$length) {
    $sound = pack(H16,"a781a700597f5900");
    $no_sound = pack(H16,"0000000000000000");
    if ($onoff == '1') {
        $out = $sound;
    } else {
        $out = $no_sound;
    }
    for ($count = $length[dot] * $units; $count > 0; $count--) {
        $return .= $out;
    }
	return $return;	
}

function check_punct($val) {
	// Replace with case
	if ($val == '.') { $val = 'PERIOD'; }
    else if ($val == ',') { $val = 'COMMA'; }
    else if ($val == ':') { $val = 'COLON'; }
    else if ($val == '?') { $val = 'QUESTION'; }
    else if ($val == "'") { $val = 'APOS'; }
    else if ($val == '-') { $val = 'HYPHEN'; }
    else if ($val == '(') { $val = 'PAREN'; }
    else if ($val == ')') { $val = 'PAREN'; }
    else if ($val == '"') { $val = 'QUOTE'; }
	else if ($val == '/') { $val = 'SLASH'; }
	else if ($val == ';') { $val = 'SEMI'; }
	else if ($val == '_') { $val = 'UNDER'; }
    else if ($val == ' ') { $val = 'SPACE'; }
	else if ($val == 'COMMA') { $val = ','; }
	else if ($val == 'PERIOD') { $val = '.'; }
	else if ($val == 'COLON') { $val = ':'; }
	else if ($val == 'QUESTION') { $val = '?'; }
	else if ($val == 'APOS') { $val = "'"; }
	else if ($val == 'HYPHEN') { $val = '-'; }
	else if ($val == 'PAREN') { $val = '('; }
	else if ($val == 'QUOTE') { $val = '"'; }
	else if ($val == 'SLASH') { $val = '/'; }
	else if ($val == 'SEMI') { $val = ';'; }
	else if ($val == 'UNDER') { $val = '_'; }
	else if ($val == 'SPACE') { $val = ' '; } 
	return $val;
}

function ascii_to_morse($in, $morse) {
	$clean = str_replace('  ', ' ', $in);
	$in_array = preg_split('//', strtoupper($clean), -1, PREG_SPLIT_NO_EMPTY); 
	foreach ($in_array as $key => $val) {
		$out[input] .= $val;
		$val = check_punct($val);
		$out[output] .= $morse[$val]." ";
	}	
	return $out;
}

function morse_to_ascii($in, $morse) {
	$in_array = split(' ', $in);	
	foreach ($in_array as $key => $val) {
		$out[input] .= $val." ";
		foreach ($morse as $foo => $bar) {
			if ($bar == $val) {
				$foo = check_punct($foo);	
				$out[output] .= $foo;
				break;
			}
		}
	}
	// Check for open and close parens...
	
	return $out;
}

function display_main($in, $listen, $wpm) {
?>
	<center>
	<h2>Morse Code Translator</h2>
	<form method="post" action="index.php">
	<b>Enter Text or Morse Code Here:</b><br>
	<font color="blue">Acceptable Entries: A-Z 0-9 . , : ; ? ' " - _ / ( )</font><br>
	<br><textarea name="user_in" rows="10" cols="80"></textarea><br>
	<br><b>Text to Morse&nbsp;</b><input type="radio" name="type" value="t_to_m" checked>&nbsp;&nbsp;<b>Morse to Text&nbsp;<input type="radio" name="type" value="m_to_t">
	&nbsp;&nbsp;<b>WPM: </b><input type="text" size="5" name="wpm" value="15"><br>
	<br><input type="submit" value="Translate Now">
	</form>
<?
	if (is_array($in)) {
		echo "<p><hr><b><u>Your Text/Code</u></b><br><br>".stripslashes($in[input]);
        echo "<p><hr><b><u>Translation</u></b><br><br>".stripslashes($in[output])."<br><br>";
		if ($listen == 1) {
			$out

Code: Select all

= $in[output];
			$out[wpm] = $wpm;
			$sound = create_sound($out);
			create_file($sound);
			echo '<embed src="temp/morse.au" volume="50" autostart="false" height="15" width="300"><br>';
		}
		echo "<br><hr>";
    } 
}

function create_file($sound) {
	$filename = 'temp/morse.au';
	$fp = fopen($filename, 'w+');
	fwrite($fp, $sound);
	fclose($fp);
}

// MAIN

$out = '';
$listen = 0;

if (isset($_POST[user_in])) {
    if ($_POST[type] == 'm_to_t') {
        $out = morse_to_ascii($_POST[user_in], $morse);
    } else if ($_POST[type] == 't_to_m') {
        $out = ascii_to_morse($_POST[user_in], $morse);
        $listen = 1;
    }
}

display_main($out, $listen, $_POST[wpm]);

?>
User avatar
skehoe
Forum Commoner
Posts: 59
Joined: Sun Dec 22, 2002 5:57 am
Location: Denver

Post by skehoe »

Sorry about the indentation on that... It seems to have disappeared when I pasted the code.
User avatar
llimllib
Moderator
Posts: 466
Joined: Mon Jul 01, 2002 2:19 pm
Location: Baltimore, MD

Post by llimllib »

no problem...very cool stuff, nice hack
Post Reply