2009-06-25 07:16:22 -07:00
|
|
|
|
/*
|
|
|
|
|
* WaveReader.cs
|
|
|
|
|
* Copyright (c) 2009 kbinani
|
|
|
|
|
*
|
|
|
|
|
* This file is part of Boare.Lib.Media.
|
|
|
|
|
*
|
|
|
|
|
* Boare.Lib.Media is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the BSD License.
|
|
|
|
|
*
|
|
|
|
|
* Boare.Lib.Media is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
*/
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if JAVA
|
|
|
|
|
package org.kbinani.media;
|
|
|
|
|
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import org.kbinani.*;
|
|
|
|
|
#else
|
2009-06-25 07:16:22 -07:00
|
|
|
|
using System;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
using bocoree;
|
|
|
|
|
using bocoree.java.io;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
namespace Boare.Lib.Media {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
using boolean = System.Boolean;
|
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if JAVA
|
|
|
|
|
public class WaveReader {
|
|
|
|
|
#else
|
|
|
|
|
public class WaveReader : IDisposable {
|
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
private int m_channel;
|
|
|
|
|
private int m_byte_per_sample;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
private boolean m_opened;
|
|
|
|
|
private RandomAccessFile m_stream;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
private int m_total_samples;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
private double m_amplify_left = 1.0;
|
|
|
|
|
private double m_amplify_right = 1.0;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// ファイル先頭から,dataチャンクまでのオフセット
|
|
|
|
|
/// </summary>
|
|
|
|
|
private int m_header_offset = 0x2e;
|
|
|
|
|
private Object m_tag = null;
|
|
|
|
|
private double m_offset_seconds = 0.0;
|
|
|
|
|
private int m_sample_per_sec;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
public WaveReader() {
|
|
|
|
|
m_opened = false;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
public WaveReader( String file )
|
|
|
|
|
#if JAVA
|
|
|
|
|
throws IOException, FileNotFoundException
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
boolean ret = open( file );
|
|
|
|
|
#if DEBUG
|
|
|
|
|
Console.WriteLine( "WaveReader#.ctor; file=" + file + "; ret=" + ret );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public double getOffsetSeconds() {
|
|
|
|
|
return m_offset_seconds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setOffsetSeconds( double value ) {
|
|
|
|
|
m_offset_seconds = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Object getTag() {
|
|
|
|
|
return m_tag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setTag( Object value ) {
|
|
|
|
|
m_tag = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public double getAmplifyLeft() {
|
|
|
|
|
return m_amplify_left;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setAmplifyLeft( double value ) {
|
|
|
|
|
m_amplify_left = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public double getAmplifyRight() {
|
|
|
|
|
return m_amplify_right;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setAmplifyRight( double value ) {
|
|
|
|
|
m_amplify_right = value;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if !JAVA
|
2009-06-25 07:16:22 -07:00
|
|
|
|
public void Dispose() {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
close();
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
public boolean open( String file )
|
|
|
|
|
#if JAVA
|
|
|
|
|
throws IOException, FileNotFoundException
|
|
|
|
|
#endif
|
|
|
|
|
{
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( m_opened ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.close();
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream = new RandomAccessFile( file, "r" );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
// RIFF
|
|
|
|
|
byte[] buf = new byte[4];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( buf[0] != 'R' || buf[1] != 'I' || buf[2] != 'F' || buf[3] != 'F' ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.close();
|
|
|
|
|
#if DEBUG
|
|
|
|
|
Console.WriteLine( "WaveReader#Open; header error(RIFF)" );
|
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ファイルサイズ - 8最後に記入
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
// WAVE
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( buf[0] != 'W' || buf[1] != 'A' || buf[2] != 'V' || buf[3] != 'E' ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.close();
|
|
|
|
|
#if DEBUG
|
|
|
|
|
Console.WriteLine( "WaveReader#Open; header error(WAVE)" );
|
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fmt
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( buf[0] != 'f' || buf[1] != 'm' || buf[2] != 't' || buf[3] != ' ' ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.close();
|
|
|
|
|
#if DEBUG
|
|
|
|
|
Console.WriteLine( "WaveReader#Open; header error(fmt )" );
|
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fmt チャンクのサイズ
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
|
|
|
|
int chunksize = (int)PortUtil.make_uint32_le( buf );
|
|
|
|
|
long fmt_chunk_end_location = m_stream.getFilePointer() + chunksize;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
// format ID
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
// チャンネル数
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
m_channel = buf[1] << 8 | buf[0];
|
|
|
|
|
|
|
|
|
|
// サンプリングレート
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
|
|
|
|
m_sample_per_sec = (int)PortUtil.make_uint32_le( buf );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
// データ速度
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
// ブロックサイズ
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
// サンプルあたりのビット数
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
int bit_per_sample = buf[1] << 8 | buf[0];
|
|
|
|
|
m_byte_per_sample = bit_per_sample / 8;
|
|
|
|
|
|
|
|
|
|
// 拡張部分
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.seek( fmt_chunk_end_location );
|
|
|
|
|
//m_stream.Read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
// data
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( buf[0] != 'd' || buf[1] != 'a' || buf[2] != 't' || buf[3] != 'a' ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.close();
|
|
|
|
|
#if DEBUG
|
|
|
|
|
Console.WriteLine( "WaveReader#Open; header error (data)" );
|
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// size of data chunk
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.read( buf, 0, 4 );
|
|
|
|
|
int size = (int)PortUtil.make_uint32_le( buf );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
m_total_samples = size / (m_channel * m_byte_per_sample);
|
|
|
|
|
|
|
|
|
|
m_opened = true;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_header_offset = (int)m_stream.getFilePointer();
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
public int getTotalSamples() {
|
|
|
|
|
return m_total_samples;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
public void read( long start, int length, double[] left, double[] right )
|
|
|
|
|
#if JAVA
|
|
|
|
|
throws IOException
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
//left = new double[length];
|
|
|
|
|
//right = new double[length];
|
2009-07-29 10:03:20 -07:00
|
|
|
|
if ( !m_opened ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
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 );
|
|
|
|
|
} else {
|
|
|
|
|
long loc = m_header_offset + m_byte_per_sample * m_channel * required_sample_start;
|
|
|
|
|
m_stream.seek( loc );
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-07-29 10:03:20 -07:00
|
|
|
|
|
|
|
|
|
if ( m_byte_per_sample == 2 ) {
|
|
|
|
|
if ( m_channel == 2 ) {
|
|
|
|
|
byte[] buf = new byte[4];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
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 );
|
2009-07-29 10:03:20 -07:00
|
|
|
|
if ( ret < 4 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
|
|
|
|
left[j] = 0.0f;
|
|
|
|
|
right[j] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
short l = (short)(buf[0] | buf[1] << 8);
|
|
|
|
|
short r = (short)(buf[2] | buf[3] << 8);
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left[i] = l * coeff_left;
|
|
|
|
|
right[i] = r * coeff_right;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
byte[] buf = new byte[2];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
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 );
|
2009-07-29 10:03:20 -07:00
|
|
|
|
if ( ret < 2 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
|
|
|
|
left[j] = 0.0f;
|
|
|
|
|
right[j] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
short l = (short)(buf[0] | buf[1] << 8);
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left[i] = l * coeff_left;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
right[i] = left[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ( m_channel == 2 ) {
|
|
|
|
|
byte[] buf = new byte[2];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
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 );
|
2009-07-29 10:03:20 -07:00
|
|
|
|
if ( ret < 2 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
|
|
|
|
left[j] = 0.0f;
|
|
|
|
|
right[j] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left[i] = (buf[0] - 64.0f) * coeff_left;
|
|
|
|
|
right[i] = (buf[1] - 64.0f) * coeff_right;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
byte[] buf = new byte[1];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
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 );
|
2009-07-29 10:03:20 -07:00
|
|
|
|
if ( ret < 1 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
|
|
|
|
left[j] = 0.0f;
|
|
|
|
|
right[j] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left[i] = (buf[0] - 64.0f) * coeff_left;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
right[i] = left[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
public void read( long start, int length, ByRef<float[]> left, ByRef<float[]> right )
|
|
|
|
|
#if JAVA
|
|
|
|
|
throws IOException
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
left.value = new float[length];
|
|
|
|
|
right.value = new float[length];
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( !m_opened ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
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.value[i] = 0.0f;
|
|
|
|
|
right.value[i] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
m_stream.seek( m_header_offset );
|
|
|
|
|
} else {
|
|
|
|
|
long loc = m_header_offset + m_byte_per_sample * m_channel * required_sample_start;
|
|
|
|
|
m_stream.seek( loc );
|
|
|
|
|
}
|
|
|
|
|
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.value[i] = 0.0f;
|
|
|
|
|
right.value[i] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
if ( m_byte_per_sample == 2 ) {
|
|
|
|
|
if ( m_channel == 2 ) {
|
|
|
|
|
byte[] buf = new byte[4];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
float coeff_left = (float)(m_amplify_left / 32768.0f);
|
|
|
|
|
float coeff_right = (float)(m_amplify_right / 32768.0f);
|
2009-06-25 07:16:22 -07:00
|
|
|
|
for ( int i = 0; i < length; i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int ret = m_stream.read( buf, 0, 4 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( ret < 4 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left.value[j] = 0.0f;
|
|
|
|
|
right.value[j] = 0.0f;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
short l = (short)(buf[0] | buf[1] << 8);
|
|
|
|
|
short r = (short)(buf[2] | buf[3] << 8);
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left.value[i] = l * coeff_left;
|
|
|
|
|
right.value[i] = r * coeff_right;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
byte[] buf = new byte[2];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
float coeff_left = (float)(m_amplify_left / 32768.0f);
|
2009-06-25 07:16:22 -07:00
|
|
|
|
for ( int i = 0; i < length; i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int ret = m_stream.read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( ret < 2 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left.value[j] = 0.0f;
|
|
|
|
|
right.value[j] = 0.0f;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
short l = (short)(buf[0] | buf[1] << 8);
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left.value[i] = l * coeff_left;
|
|
|
|
|
right.value[i] = left.value[i];
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ( m_channel == 2 ) {
|
|
|
|
|
byte[] buf = new byte[2];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
float coeff_left = (float)(m_amplify_left / 64.0f);
|
|
|
|
|
float coeff_right = (float)(m_amplify_right / 64.0f);
|
2009-06-25 07:16:22 -07:00
|
|
|
|
for ( int i = 0; i < length; i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int ret = m_stream.read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( ret < 2 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left.value[j] = 0.0f;
|
|
|
|
|
right.value[j] = 0.0f;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left.value[i] = (buf[0] - 64.0f) * coeff_left;
|
|
|
|
|
right.value[i] = (buf[1] - 64.0f) * coeff_right;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
byte[] buf = new byte[1];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
float coeff_left = (float)(m_amplify_left / 64.0f);
|
2009-06-25 07:16:22 -07:00
|
|
|
|
for ( int i = 0; i < length; i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int ret = m_stream.read( buf, 0, 1 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( ret < 1 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left.value[j] = 0.0f;
|
|
|
|
|
right.value[j] = 0.0f;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left.value[i] = (buf[0] - 64.0f) * coeff_left;
|
|
|
|
|
right.value[i] = left.value[i];
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if !JAVA
|
|
|
|
|
public unsafe void read( long start, int length, ref IntPtr ptr_left, ref IntPtr ptr_right ) {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
float* left = (float*)ptr_left.ToPointer();
|
|
|
|
|
float* right = (float*)ptr_right.ToPointer();
|
|
|
|
|
if ( !m_opened ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
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 );
|
|
|
|
|
} else {
|
|
|
|
|
long loc = m_header_offset + m_byte_per_sample * m_channel * required_sample_start;
|
|
|
|
|
m_stream.seek( loc );
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
if ( m_byte_per_sample == 2 ) {
|
|
|
|
|
if ( m_channel == 2 ) {
|
|
|
|
|
byte[] buf = new byte[4];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
float coeff_left = (float)(m_amplify_left / 32768.0f);
|
|
|
|
|
float coeff_right = (float)(m_amplify_right / 32768.0f);
|
2009-06-25 07:16:22 -07:00
|
|
|
|
for ( int i = 0; i < length; i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int ret = m_stream.read( buf, 0, 4 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( ret < 4 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
|
|
|
|
left[j] = 0.0f;
|
|
|
|
|
right[j] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
short l = (short)(buf[0] | buf[1] << 8);
|
|
|
|
|
short r = (short)(buf[2] | buf[3] << 8);
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left[i] = l * coeff_left;
|
|
|
|
|
right[i] = r * coeff_right;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
byte[] buf = new byte[2];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
float coeff_left = (float)(m_amplify_left / 32768.0f);
|
2009-06-25 07:16:22 -07:00
|
|
|
|
for ( int i = 0; i < length; i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int ret = m_stream.read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( ret < 2 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
|
|
|
|
left[j] = 0.0f;
|
|
|
|
|
right[j] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
short l = (short)(buf[0] | buf[1] << 8);
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left[i] = l * coeff_left;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
right[i] = left[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ( m_channel == 2 ) {
|
|
|
|
|
byte[] buf = new byte[2];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
float coeff_left = (float)(m_amplify_left / 64.0f);
|
|
|
|
|
float coeff_right = (float)(m_amplify_right / 64.0f);
|
2009-06-25 07:16:22 -07:00
|
|
|
|
for ( int i = 0; i < length; i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int ret = m_stream.read( buf, 0, 2 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( ret < 2 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
|
|
|
|
left[j] = 0.0f;
|
|
|
|
|
right[j] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left[i] = (buf[0] - 64.0f) * coeff_left;
|
|
|
|
|
right[i] = (buf[1] - 64.0f) * coeff_right;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
byte[] buf = new byte[1];
|
2010-03-16 20:14:08 -07:00
|
|
|
|
float coeff_left = (float)(m_amplify_left / 64.0f);
|
2009-06-25 07:16:22 -07:00
|
|
|
|
for ( int i = 0; i < length; i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int ret = m_stream.read( buf, 0, 1 );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
if ( ret < 1 ) {
|
|
|
|
|
for ( int j = i; j < length; j++ ) {
|
|
|
|
|
left[j] = 0.0f;
|
|
|
|
|
right[j] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
left[i] = (buf[0] - 64.0f) * coeff_left;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
right[i] = left[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
public void close()
|
|
|
|
|
#if JAVA
|
|
|
|
|
throws IOException
|
|
|
|
|
#endif
|
|
|
|
|
{
|
2009-06-25 07:16:22 -07:00
|
|
|
|
m_opened = false;
|
|
|
|
|
if ( m_stream != null ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_stream.close();
|
2009-07-29 10:03:20 -07:00
|
|
|
|
m_stream = null;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if !JAVA
|
2009-06-25 07:16:22 -07:00
|
|
|
|
~WaveReader() {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
close();
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if !JAVA
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#endif
|