public function write()
 {
     // remove existing apetag
     $this->remove();
     $engine = new getid3();
     $engine->filename = $this->filename;
     $engine->fp = fopen($this->filename, 'rb');
     $engine->include_module('tag.id3v1');
     $engine->include_module('tag.lyrics3');
     $tag = new getid3_id3v1($engine);
     $tag->Analyze();
     $tag = new getid3_lyrics3($engine);
     $tag->Analyze();
     $apetag = $this->generate_tag();
     if (!($fp = @fopen($this->filename, 'a+b'))) {
         throw new getid3_exception('Could not open a+b: ' . $this->filename);
     }
     // init: audio ends at eof
     $post_audio_offset = filesize($this->filename);
     // lyrics3 tag present
     if (@$engine->info['lyrics3']['tag_offset_start']) {
         // audio ends before lyrics3 tag
         $post_audio_offset = @$engine->info['lyrics3']['tag_offset_start'];
     } elseif (@$engine->info['id3v1']['tag_offset_start']) {
         // audio ends before id3v1 tag
         $post_audio_offset = $engine->info['id3v1']['tag_offset_start'];
     }
     // seek to end of audio data
     fseek($fp, $post_audio_offset, SEEK_SET);
     // save data after audio data
     $post_audio_data = '';
     if (filesize($this->filename) > $post_audio_offset) {
         $post_audio_data = fread($fp, filesize($this->filename) - $post_audio_offset);
     }
     // truncate file before start of new apetag
     fseek($fp, $post_audio_offset, SEEK_SET);
     ftruncate($fp, ftell($fp));
     // write new apetag
     fwrite($fp, $apetag, strlen($apetag));
     // rewrite data after audio
     if (!empty($post_audio_data)) {
         fwrite($fp, $post_audio_data, strlen($post_audio_data));
     }
     fclose($fp);
     clearstatcache();
     return true;
 }
 public function remove()
 {
     $engine = new getid3();
     $engine->filename = $this->filename;
     $engine->fp = fopen($this->filename, 'rb');
     $engine->include_module('tag.lyrics3');
     $tag = new getid3_lyrics3($engine);
     $tag->Analyze();
     if (isset($engine->info['lyrics3']['tag_offset_start']) && isset($engine->info['lyrics3']['tag_offset_end'])) {
         if (!($fp = @fopen($this->filename, 'a+b'))) {
             throw new getid3_exception('Could not open a+b: ' . $this->filename);
         }
         // get data after tag
         fseek($fp, $engine->info['lyrics3']['tag_offset_end'], SEEK_SET);
         $data_after_lyrics3 = '';
         if (filesize($this->filename) > $engine->info['lyrics3']['tag_offset_end']) {
             $data_after_lyrics3 = fread($fp, filesize($this->filename) - $engine->info['lyrics3']['tag_offset_end']);
         }
         // truncate file before start of tag and seek to end
         ftruncate($fp, $engine->info['lyrics3']['tag_offset_start']);
         // rewrite data after tag
         if (!empty($data_after_lyrics3)) {
             fseek($fp, $engine->info['lyrics3']['tag_offset_start'], SEEK_SET);
             fwrite($fp, $data_after_lyrics3, strlen($data_after_lyrics3));
         }
         fclose($fp);
         clearstatcache();
     }
     // success when removing non-existant tag
     return true;
 }