public unsafe void read(long start, int length, ref IntPtr ptr_left, ref IntPtr ptr_right)
        {
            float *left  = (float *)ptr_left.ToPointer();
            float *right = (float *)ptr_right.ToPointer();

            if (!m_opened)
            {
                return;
            }
            int  i_start = 0;
            int  i_end   = length;
            long required_sample_start = start + (long)(m_offset_seconds * m_sample_per_sec);
            long required_sample_end   = required_sample_start + length;

            // 第required_sample_startサンプルから,第required_sample_endサンプルまでの読み込みが要求された.
            if (required_sample_start < 0)
            {
                i_start = -(int)required_sample_start + 1;
                // 0 -> i_start - 1までは0で埋める
                for (int i = 0; i < i_start; i++)
                {
                    left[i]  = 0.0f;
                    right[i] = 0.0f;
                }
                m_stream.Seek(m_header_offset, SeekOrigin.Begin);
            }
            else
            {
                long loc = m_header_offset + m_byte_per_sample * m_channel * required_sample_start;
                m_stream.Seek(loc, SeekOrigin.Begin);
            }
            if (m_total_samples < required_sample_end)
            {
                i_end = length - 1 - (int)required_sample_end + m_total_samples;
                // i_end + 1 -> length - 1までは0で埋める
                for (int i = i_end + 1; i < length; i++)
                {
                    left[i]  = 0.0f;
                    right[i] = 0.0f;
                }
            }

            if (m_byte_per_sample == 2)
            {
                if (m_channel == 2)
                {
                    byte[] buf         = new byte[4];
                    float  coeff_left  = (float)(m_amplify_left / 32768.0f);
                    float  coeff_right = (float)(m_amplify_right / 32768.0f);
                    for (int i = 0; i < length; i++)
                    {
                        int ret = m_stream.Read(buf, 0, 4);
                        if (ret < 4)
                        {
                            for (int j = i; j < length; j++)
                            {
                                left[j]  = 0.0f;
                                right[j] = 0.0f;
                            }
                            break;
                        }
                        short l = PortUtil.make_int16_le(buf, 0);
                        short r = PortUtil.make_int16_le(buf, 2);
                        left[i]  = l * coeff_left;
                        right[i] = r * coeff_right;
                    }
                }
                else
                {
                    byte[] buf        = new byte[2];
                    float  coeff_left = (float)(m_amplify_left / 32768.0f);
                    for (int i = 0; i < length; i++)
                    {
                        int ret = m_stream.Read(buf, 0, 2);
                        if (ret < 2)
                        {
                            for (int j = i; j < length; j++)
                            {
                                left[j]  = 0.0f;
                                right[j] = 0.0f;
                            }
                            break;
                        }
                        short l = PortUtil.make_int16_le(buf, 0);
                        left[i]  = l * coeff_left;
                        right[i] = left[i];
                    }
                }
            }
            else
            {
                if (m_channel == 2)
                {
                    byte[] buf         = new byte[2];
                    float  coeff_left  = (float)(m_amplify_left / 64.0f);
                    float  coeff_right = (float)(m_amplify_right / 64.0f);
                    for (int i = 0; i < length; i++)
                    {
                        int ret = m_stream.Read(buf, 0, 2);
                        if (ret < 2)
                        {
                            for (int j = i; j < length; j++)
                            {
                                left[j]  = 0.0f;
                                right[j] = 0.0f;
                            }
                            break;
                        }
                        left[i]  = ((0xff & buf[0]) - 64.0f) * coeff_left;
                        right[i] = ((0xff & buf[1]) - 64.0f) * coeff_right;
                    }
                }
                else
                {
                    byte[] buf        = new byte[1];
                    float  coeff_left = (float)(m_amplify_left / 64.0f);
                    for (int i = 0; i < length; i++)
                    {
                        int ret = m_stream.Read(buf, 0, 1);
                        if (ret < 1)
                        {
                            for (int j = i; j < length; j++)
                            {
                                left[j]  = 0.0f;
                                right[j] = 0.0f;
                            }
                            break;
                        }
                        left[i]  = ((0xff & buf[0]) - 64.0f) * coeff_left;
                        right[i] = left[i];
                    }
                }
            }
        }
        public void read(long start, int length, double[] left, double[] right)
        {
            for (int i = 0; i < length; i++)
            {
                left[i]  = 0.0;
                right[i] = 0.0;
            }
            //left = new double[length];
            //right = new double[length];
            if (!m_opened)
            {
                return;
            }
            int  i_start = 0;
            int  i_end   = length - 1;
            long required_sample_start = start + (long)(m_offset_seconds * m_sample_per_sec);
            long required_sample_end   = required_sample_start + length;

            // 第required_sample_startサンプルから,第required_sample_endサンプルまでの読み込みが要求された.
            if (required_sample_start < 0)
            {
                i_start = -(int)required_sample_start + 1;
                // 0 -> i_start - 1までは0で埋める
                if (i_start >= length)
                {
                    // 全部0で埋める必要のある場合.
                    for (int i = 0; i < length; i++)
                    {
                        left[i]  = 0.0;
                        right[i] = 0.0;
                    }
                    return;
                }
                else
                {
                    for (int i = 0; i < i_start; i++)
                    {
                        left[i]  = 0.0;
                        right[i] = 0.0;
                    }
                }
                m_stream.Seek(m_header_offset, SeekOrigin.Begin);
            }
            else
            {
                long loc = m_header_offset + m_byte_per_sample * m_channel * required_sample_start;
                m_stream.Seek(loc, SeekOrigin.Begin);
            }
            if (m_total_samples < required_sample_end)
            {
                i_end = length - 1 - (int)required_sample_end + m_total_samples;
                // i_end + 1 -> length - 1までは0で埋める
                if (i_end < 0)
                {
                    // 全部0で埋める必要のある場合
                    for (int i = 0; i < length; i++)
                    {
                        left[i]  = 0.0;
                        right[i] = 0.0;
                    }
                    return;
                }
                else
                {
                    for (int i = i_end + 1; i < length; i++)
                    {
                        left[i]  = 0.0;
                        right[i] = 0.0;
                    }
                }
            }

            if (m_byte_per_sample == 2)
            {
                if (m_channel == 2)
                {
                    byte[] buf         = new byte[4];
                    double coeff_left  = m_amplify_left / 32768.0;
                    double coeff_right = m_amplify_right / 32768.0;
                    for (int i = i_start; i <= i_end; i++)
                    {
                        int ret = m_stream.Read(buf, 0, 4);
                        if (ret < 4)
                        {
                            for (int j = i; j < length; j++)
                            {
                                left[j]  = 0.0f;
                                right[j] = 0.0f;
                            }
                            break;
                        }
                        short l = PortUtil.make_int16_le(buf, 0);
                        short r = PortUtil.make_int16_le(buf, 2);
                        left[i]  = l * coeff_left;
                        right[i] = r * coeff_right;
                    }
                }
                else
                {
                    byte[] buf        = new byte[2];
                    double coeff_left = m_amplify_left / 32768.0;
                    for (int i = i_start; i <= i_end; i++)
                    {
                        int ret = m_stream.Read(buf, 0, 2);
                        if (ret < 2)
                        {
                            for (int j = i; j < length; j++)
                            {
                                left[j]  = 0.0f;
                                right[j] = 0.0f;
                            }
                            break;
                        }
                        short l = PortUtil.make_int16_le(buf, 0);
                        left[i]  = l * coeff_left;
                        right[i] = left[i];
                    }
                }
            }
            else
            {
                if (m_channel == 2)
                {
                    byte[] buf         = new byte[2];
                    double coeff_left  = m_amplify_left / 64.0;
                    double coeff_right = m_amplify_right / 64.0;
                    for (int i = i_start; i <= i_end; i++)
                    {
                        int ret = m_stream.Read(buf, 0, 2);
                        if (ret < 2)
                        {
                            for (int j = i; j < length; j++)
                            {
                                left[j]  = 0.0f;
                                right[j] = 0.0f;
                            }
                            break;
                        }
                        left[i]  = ((0xff & buf[0]) - 64.0f) * coeff_left;
                        right[i] = ((0xff & buf[1]) - 64.0f) * coeff_right;
                    }
                }
                else
                {
                    byte[] buf        = new byte[1];
                    double coeff_left = m_amplify_left / 64.0;
                    for (int i = i_start; i <= i_end; i++)
                    {
                        int ret = m_stream.Read(buf, 0, 1);
                        if (ret < 1)
                        {
                            for (int j = i; j < length; j++)
                            {
                                left[j]  = 0.0f;
                                right[j] = 0.0f;
                            }
                            break;
                        }
                        left[i]  = ((0xff & buf[0]) - 64.0f) * coeff_left;
                        right[i] = left[i];
                    }
                }
            }
        }