public bool open(string file)
        {
#if DEBUG
            sout.println("WaveReader#open; file=" + file);
#endif
            if (m_opened)
            {
                m_stream.Close();
            }
            m_stream = new FileStream(file, FileMode.Open, FileAccess.Read);

            // RIFF
            byte[] buf = new byte[4];
            m_stream.Read(buf, 0, 4);
            if (buf[0] != 'R' || buf[1] != 'I' || buf[2] != 'F' || buf[3] != 'F')
            {
                m_stream.Close();
#if DEBUG
                serr.println("WaveReader#open; header error(RIFF)");
#endif
                return(false);
            }

            // ファイルサイズ - 8最後に記入
            m_stream.Read(buf, 0, 4);

            // WAVE
            m_stream.Read(buf, 0, 4);
            if (buf[0] != 'W' || buf[1] != 'A' || buf[2] != 'V' || buf[3] != 'E')
            {
                m_stream.Close();
#if DEBUG
                serr.println("WaveReader#open; header error(WAVE)");
#endif
                return(false);
            }

            // fmt
            m_stream.Read(buf, 0, 4);
            if (buf[0] != 'f' || buf[1] != 'm' || buf[2] != 't' || buf[3] != ' ')
            {
                m_stream.Close();
#if DEBUG
                serr.println("WaveReader#open; header error(fmt )");
#endif
                return(false);
            }

            // fmt チャンクのサイズ
            m_stream.Read(buf, 0, 4);
            int  chunksize = (int)PortUtil.make_uint32_le(buf);
            long fmt_chunk_end_location = m_stream.Position + chunksize;

            // format ID
            m_stream.Read(buf, 0, 2);

            // チャンネル数
            m_stream.Read(buf, 0, 2);
            m_channel = buf[1] << 8 | buf[0];
#if DEBUG
            sout.println("WaveReader#open; m_channel=" + m_channel);
#endif

            // サンプリングレート
            m_stream.Read(buf, 0, 4);
            m_sample_per_sec = (int)PortUtil.make_uint32_le(buf);
#if DEBUG
            sout.println("WaveReader#open; m_sample_per_sec=" + m_sample_per_sec);
#endif

            // データ速度
            m_stream.Read(buf, 0, 4);

            // ブロックサイズ
            m_stream.Read(buf, 0, 2);

            // サンプルあたりのビット数
            m_stream.Read(buf, 0, 2);
            int bit_per_sample = buf[1] << 8 | buf[0];
            m_byte_per_sample = bit_per_sample / 8;
#if DEBUG
            sout.println("WaveReader#open; m_byte_per_sample=" + m_byte_per_sample);
#endif

            // 拡張部分
            m_stream.Seek(fmt_chunk_end_location, SeekOrigin.Begin);
            //m_stream.Read( buf, 0, 2 );

            // data
            m_stream.Read(buf, 0, 4);
            if (buf[0] != 'd' || buf[1] != 'a' || buf[2] != 't' || buf[3] != 'a')
            {
                m_stream.Close();
#if DEBUG
                serr.println("WaveReader#open; header error (data)");
#endif
                return(false);
            }

            // size of data chunk
            m_stream.Read(buf, 0, 4);
            int size = (int)PortUtil.make_uint32_le(buf);
            m_total_samples = size / (m_channel * m_byte_per_sample);
#if DEBUG
            sout.println("WaveReader#open; m_total_samples=" + m_total_samples + "; total sec=" + (m_total_samples / (double)m_sample_per_sec));
#endif

            m_opened        = true;
            m_header_offset = (int)m_stream.Position;
            return(true);
        }