<?php
/*
* WavForge PHP WAV Generation Class
* Version 0.2 Beta
* Created by sk89q
* http://www.therisenrealm.com
*
* Copyright (c) 2004, sk89q
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of sk89q nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class WavForge
{
// Public
var $channels = 2;
var $sample_rate = 44100;
var $bits_per_sample = 16;
// Private
var $samples = 0;
var $output;
function output_wav()
{
return $this->output_header() . $this->output;
}
function write_wav( $filename, $mode = 'w' )
{
if( $fp = fopen( $filename, $mode ) )
{
fwrite( $fp, $this->output_header() . $this->output );
fclose( $fp );
return true;
}
else
{
return false;
}
}
function output_header()
{
$subchunk_2_size = $this->samples * $this->channels * $this->bits_per_sample / 8;
$header .= pack( 'N*', 0x52494646 ); // ChunkID [0,4] RIFF
$header .= pack( 'V*', $subchunk_2_size + 36 ); // ChunkSize [0,4]
$header .= pack( 'N*', 0x57415645 ); // Format [8,4] WAVE
$header .= pack( 'N*', 0x666d7420 ); // Subchunk1ID [12,4] fmt
$header .= pack( 'V*', 16 ); // Subchunk1Size [16,4] 16 for PCM
$header .= pack( 'v*', 1 ); // AudioFormat [20,2] 1 for PCM
$header .= pack( 'v*', $this->channels ); // NumChannels [22,2] 1 for mono, 2 for stereo
$header .= pack( 'V*', $this->sample_rate ); // SampleRate [24,4]
$header .= pack( 'V*', $this->sample_rate * $this->channels * $this->bits_per_sample / 8 ); // ByteRate [28,4] SampleRate * NumChannels * BitsPerSample / 8
$header .= pack( 'v*', $this->channels * $this->bits_per_sample / 8 ); // BlockAlign [32,2] NumChannels * BitsPerSample / 8
$header .= pack( 'v*', $this->bits_per_sample ); // BitsPerSample [34,2]
$header .= pack( 'N*', 0x64617461 ); // Subchunk1ID [36,4] data
$header .= pack( 'V*', $subchunk_2_size ); // Subchunk2Size [40,4]
return $header;
}
function synth_sine( $frequency, $volume, $seconds )
{
for( $i = 0; $i < $seconds * $this->sample_rate; $i++ )
{
for( $c = 0; $c < $this->channels; $c++ )
{
$this->output .= pack( 'v*', (double) ( $volume * sin( 2 * 3.14159265358979 * $i * $frequency / $this->sample_rate ) ) );
}
$this->samples++;
}
}
}
?>