이 코드는 트릭을 수행해야합니다. 그것은 웨이브 파일을 정규화 된 double 배열 (-1 대 1)로 변환하지만 int/short 배열로 바꾸는 것은 간단합니다 (/32768.0 비트를 제거하고 대신 32768을 추가하십시오). 로드 된 wav 파일이 모노 인 경우 right [] 배열이 null로 설정됩니다.
완전히 불완전하다는 주장은 할 수 없지만 (65536 개의 샘플 배열을 만들고 -1에서 1로 웨이브를 생성 한 후에는 샘플이 전혀 나타나지 않습니다. 천장이나 바닥. 당신이 다음 WAV 파일을 가정, 플러그인을 사용하고자하는 경우
// convert two bytes to one double in the range -1 to 1
static double bytesToDouble(byte firstByte, byte secondByte)
{
// convert two bytes to one short (little endian)
short s = (secondByte << 8) | firstByte;
// convert to range from -1 to (just below) 1
return s/32768.0;
}
// Returns left and right double arrays. 'right' will be null if sound is mono.
public void openWav(string filename, out double[] left, out double[] right)
{
byte[] wav = File.ReadAllBytes(filename);
// Determine if mono or stereo
int channels = wav[22]; // Forget byte 23 as 99.999% of WAVs are 1 or 2 channels
// Get past all the other sub chunks to get to the data subchunk:
int pos = 12; // First Subchunk ID from 12 to 16
// Keep iterating until we find the data chunk (i.e. 64 61 74 61 ...... (i.e. 100 97 116 97 in decimal))
while(!(wav[pos]==100 && wav[pos+1]==97 && wav[pos+2]==116 && wav[pos+3]==97))
{
pos += 4;
int chunkSize = wav[pos] + wav[pos + 1] * 256 + wav[pos + 2] * 65536 + wav[pos + 3] * 16777216;
pos += 4 + chunkSize;
}
pos += 8;
// Pos is now positioned to start of actual sound data.
int samples = (wav.Length - pos)/2; // 2 bytes per sample (16 bit sound mono)
if (channels == 2)
{
samples /= 2; // 4 bytes per sample (16 bit stereo)
}
// Allocate memory (right will be null if only mono sound)
left = new double[samples];
if (channels == 2)
{
right = new double[samples];
}
else
{
right = null;
}
// Write to double array/s:
int i=0;
while (pos < length)
{
left[i] = bytesToDouble(wav[pos], wav[pos + 1]);
pos += 2;
if (channels == 2)
{
right[i] = bytesToDouble(wav[pos], wav[pos + 1]);
pos += 2;
}
i++;
}
}
는 (가장 일반적입니다) 16 비트 PCM, 당신은 바이트 배열로 그것을 읽어 NAudio를 사용하고, 다음에 있음을 복사 할 수 있습니다 포함되어 있습니다 편의상 16 비트 정수 배열. 스테레오 인 경우 샘플이 왼쪽, 오른쪽으로 인터리브됩니다.
using (WaveFileReader reader = new WaveFileReader("myfile.wav"))
{
Assert.AreEqual(16, reader.WaveFormat.BitsPerSample, "Only works with 16 bit audio");
byte[] buffer = new byte[reader.Length];
int read = reader.Read(buffer, 0, buffer.Length);
short[] sampleBuffer = new short[read/2];
Buffer.BlockCopy(buffer, 0, sampleBuffer, 0, read);
}
개인적으로 가능한 한 제 3 자 라이브러리를 사용하지 마십시오. 그러나 코드를 더 잘 보이게 처리하려면이 옵션을 그대로 사용하십시오.
26 바이트 크기를 볼 때 즉시 잘못 알아야합니다. – Steve
데이터 ID의 값을 확인하십시오. 그것은 "fmt"문자를 포함해야합니다. 32 비트 int로 읽으면 다음과 같은 내용이 포함될 것임을 의미합니다. 0x20 0x74 0x6d 0x66. 그러면 올바른 위치에서 dataSize 값을 읽는 지 확인할 수 있습니다. – Olan