public function readWavData($dataOffset = 0, $dataSize = null)
    {
        // check preconditions
        if (!is_resource($this->_fp)) {
            throw new WavFileException('No wav file open. Use openWav() first.');
        }

        if ($dataOffset < 0 || $dataOffset % $this->getBlockAlign() > 0) {
            throw new WavFileException('Invalid data offset. Has to be a multiple of BlockAlign.');
        }

        if (is_null($dataSize)) {
            $dataSize = $this->_dataSize_fp - ($this->_dataSize_fp % $this->getBlockAlign());  // only read complete blocks
        } elseif ($dataSize < 0 || $dataSize % $this->getBlockAlign() > 0) {
            throw new WavFileException('Invalid data size to read. Has to be a multiple of BlockAlign.');
        }


        // skip offset
        if ($dataOffset > 0 && fseek($this->_fp, $dataOffset, SEEK_CUR) !== 0) {
            throw new WavFileException('Seeking to data offset failed.');
        }

        // read data
        $this->_samples .= fread($this->_fp, $dataSize);  // allow appending
        $this->setDataSize();  // implicit setSize(), setActualSize(), setNumBlocks()

        // close file or memory stream
        return $this->closeWav();
    }