간단한 실시간 오디오 라이브러리를 개발 중입니다. 프로그래머는 실시간으로 오디오를 재생할 수있는 메서드를 호출 할 수 있습니다. 또한 프로그래머는 특정 주파수와 지속 시간으로 사인파를 실시간으로 재생할 수있는 메서드를 호출 할 수 있습니다. 실시간으로 재생되는 오디오 형식은 WAV입니다. 문제는 PlayerSound.Play가 사운드를 재생할 수 없다는 내부 예외를 throw하는 playSineWave를 호출 할 때 손상된 헤더가 있기 때문입니다. 그래서 처음에는 실수로 우물을 잘못 작성했다고 믿었습니다. 그러나 물론 헤더를 포함하여 wav 파일의 실제 바이트를 저장했는데 오류없이 iTunes에서 재생했고 올바른 주파수의 사인파처럼 들립니다. 그래서 던져지고있는 예외가 오도 된 것이므로 잘못된 것은 무엇입니까.SoundPlayer는 웨이브 헤더가 손상되었지만 그렇지 않은 예외를 throw합니다.
public void playSineWave(int frequency, int totalSampleLength)
{
if (frequency <= 0)
{
throw new InvalidDataException("frequency cannot be zero or negative.");
}
List<byte> data = new List<byte>();
byte[] header = getWavHeader(totalSampleLength);
data.AddRange(header);
for(int x = 0; x < (totalSampleLength); x++)
{
data.Add((byte)(127 * Math.Sin(2 * (Math.PI/sampleRate) * frequency * (x/2))));
}
using(MemoryStream stream = new MemoryStream())
{
using (SoundPlayer player = new SoundPlayer(stream))
{
stream.Write(data.ToArray(), 0, data.Count);
player.Play();
}
}
}
public int secondsToSampleLength(int seconds)
{
/*
* x sample 2 byte 60 second
* -------- * -------- * --------------- = total in samples
* 1 second 1 second 1 second
*/
return sampleRate * seconds * 2;
}
private byte[] getWavHeader(int totalSamples)
{
MemoryStream stream = new MemoryStream();
byte[] wavHeader;
using (BinaryWriter writer = new BinaryWriter(stream, Encoding.BigEndianUnicode))
{
writer.Write(new byte[] { 0x52, 0x49, 0x46, 0x46 }); // 4
int bitsPerSample = 16;
writer.Write(36 + (totalSamples * numberOfChannels * (bitsPerSample/8))); // 4
writer.Write(new byte[] { 0x57, 0x41, 0x56, 0x45 }); // 4
writer.Write(new byte[] { 0x66, 0x6d, 0x74, 0x20 }); // 4
writer.Write(16); // 4
writer.Write((short)1); // 2
writer.Write((short)numberOfChannels); // 2
writer.Write(sampleRate); // 4
writer.Write(sampleRate * numberOfChannels * (bitsPerSample/8)); // 4
writer.Write((short)(numberOfChannels * (bitsPerSample/8))); // 2
writer.Write((short)(bitsPerSample)); // 2
writer.Write(new byte[] { 0x64, 0x61, 0x74, 0x61 }); // 4
writer.Write((totalSamples * numberOfChannels * (bitsPerSample/8))); // 4
wavHeader = stream.ToArray();
}
return wavHeader;
}
내가 WAV 파일을 재생할 수있는 Windows API의 방법을 사용해야합니다 : 여기
는 문제의 원인이되는 코드는? 어떤 제안도 도움이 될 것입니다. 고맙습니다. WAV 파일을 처음부터 작성하고 싶습니다. 훌륭한 라이브러리를 알고 있습니다.보호 된 메모리를 읽거나 쓰려고 시도 :
내가 다음 작성 후 제로로 높은 게재 순위를 설정하면 그 아래에이 예외를 제공한다는 얘기를 깜빡 했네요. 이것은 종종 다른 메모리가 손상되었다는 표시입니다.
WAV 파일은 * byte *가 아니며 RIFF 표준 (Resource Interchange File Format)에 의해 지정된 구조를 가진 파일 형식입니다. SoundPlayer는 원시 샘플 데이터 (일명 PCM)를 재생하는 방법을 알지 못합니다 *. NAudio를 사용하지 않으려면 wav 스트림 작성기를 직접 만들어야합니다. –