설명하기가 너무 복잡해 질 수는 있지만 간단하지만 유익한 정보로 유지하려고 노력할 것입니다. C# .net으로 작성된 내 프로그램은 2 초 동안 마이크를 모니터링하고 샘플에서 최대 값을 반환합니다. WinMil.dll에서 소리 등을 생성하는 방법에 능숙하지는 않지만 내 프로그램은 NAudio와 CodeProject의 다른 프로젝트를 기반으로 파도를 시각화합니다. 내가 사용하고 웨이브 형식이 웨이브에서 숫자가 커지지 않게하는 방법
//WaveIn.cs
private WaveFormat Format= new WaveFormat(8000, 16,1);
//waveFormat.cs
[StructLayout(LayoutKind.Sequential)]
public class WaveFormat
{
public short wFormatTag;
public short nChannels;
public int nSamplesPerSec;
public int nAvgBytesPerSec;
public short nBlockAlign;
public short wBitsPerSample;
public short cbSize;
public WaveFormat(int rate, int bits, short channels)
{
wFormatTag = (short)WaveFormats.Pcm;
nChannels = channels;
nSamplesPerSec = rate;
wBitsPerSample = (short)bits;
cbSize = 0;
nBlockAlign = (short)(nChannels * (wBitsPerSample/8));
nAvgBytesPerSec = nSamplesPerSec * nBlockAlign;
}
(난 그냥이를 게시하여, 내 문제를 발견 할 수 있습니다 생각하지만 난 여전히 물어거야)
그래서 다음 카드를 설치 이벤트를을 내 웨이브 파일의 최대 사운드 레벨. 소스 코드가 올바르게 이해되면 버퍼가 가득 차면 실행됩니다. 여기에 내가 여기이 테스트에서 모니터 할 때 나는 소음 수준을 유지하는 경우 때문에 충돌하지 않습니다 그 코드
private void CallBack(IntPtr waveInHandle, WaveMessage message, int userData, ref WaveHeader waveHeader, IntPtr reserved)
{
if (message == WaveMessage.WIM_DATA)
{
GCHandle hBuffer = (GCHandle)waveHeader.dwUser;
WaveInBuffer buffer = (WaveInBuffer)hBuffer.Target;
Exception exception = null;
if (DataAvailable != null)
{
DataAvailable(buffer.Data, buffer.BytesRecorded);
}
if (MaxSoundLevel != null) //FOLLOW THIS ONE
{
byte[] waveStream = new byte[buffer.BytesRecorded];
Marshal.Copy(buffer.Data, waveStream, 0, buffer.BytesRecorded);
MaxSoundLevel(GetMaxSound(GetWaveChannels(waveStream)));
}
if (recording)
{
try
{
buffer.Reuse();
}
catch (Exception e)
{
recording = false;
exception = e;
}
}
}
}
private short[] GetWaveChannels(byte[] waveStream)
{
short[] monoWave = new short[waveStream.Length/2];
int h=0;
for (int i = 0 ; i < waveStream.Length; i += 2)
{
monoWave[h] = BitConverter.ToInt16(waveStream, i);
h++;
}
return monoWave;
}
private int GetMaxSound(short[] wave)
{
int maxSound = 0;
for (int i = 0; i < wave.Length; i++)
{
maxSound = Math.Max(maxSound, Math.Abs(wave[i]));
}
return maxSound;
}
가 "정상"
[Test]
public void TestSound()
{
var waveIn = new WaveIn();
waveIn.MaxSoundLevel += new WaveIn.MaxSoundHandler(waveIn_MaxSoundLevel);
waveIn.StartRecording();
Console.WriteLine("Starting to record");
Thread.Sleep(4800); //record for 4.8 seconds.
waveIn.StopRecording();
Console.WriteLine("Done Recording");
}
void waveIn_MaxSoundLevel(int MaxSound)
{
Console.WriteLine("MaxSound:{0}", MaxSound);
}
여기 내 출력
MaxSound입니다 28 MaxSound 24 MaxSound 31 MaxSound 17 MaxSound : 18,760
되지 않은 전 ception : System.OverflowException : 2 진수의 최소값을 부정하면 유효하지 않습니다.
나는 한번 MaxSound : 32767 (0x7FFF)을 주었다.
그래서 내 문제가 32 비트 숫자를 16 비트 숫자로 변환하려고 시도하는 동안 거짓말을 했으므로 GetMaxSound를 short에서 int로 전환했습니다. 그래서 나는 모른다. 나는 곤두박질 친다. 그런데 왜이 문제가 있습니까? 내 웨이브가 최대 32,767이고 winmm.dll이이를 알고 그것을 지나치지 않는다고 제안합니까? 그리고이 문제가 발생하지 않는다면 단지 2 바이트의 데이터를 short로 변환하기 때문에? 제발 도와주세요 :)
을한다 하나의 웨이브에 대해 시스템이 성공적으로 실행 되었기 때문에 32,767 "**이라는 결과가 다음 웨이브에 적용될 것이라는 의미는 아니며 시스템이 동일한 파일을 여러 번 실행하는 경우 다르게 작동한다고 말하는 것입니까? 또한 당신은'GetMaxSound'를 바꾸었지만 당신은'BitConverter.ToInt16'에서 떠났습니다. –
@ JoshuaDrake이 웨이브는 웨이브 파일이 아니라 내 마이크에서 가져온 것입니다. 내 마이크에서 시끄러운 소리를 내지 않으면 소리가 나지 않습니다. 'GetMaxSound'를 사용하여 연주하는 것은 그것이 설정과 충돌 할 수 있음을 완전히 이해하지 못하는 것입니다. 그것은 비트 컨버터 오버플로 결코 실행해서는 안된다 ??? 그리고 32767 또는 -32768을 돌려 주면 안됩니다 ... 잠시 복근을 사용하겠습니다. 어떤 32768 오버플로 허 ... BRB –
그게 다야! 나는 내 웨이브에 int를 던져서 32768에 맥스 아웃한다. :) maxSound = Math.Max (maxSound, Math.Abs ((int) wave [i]))'는 해결책이다. 나는 그것을 불어서 다음과 같은 결과를 얻었다.MaxSound : 399 MaxSound 320 MaxSound 264 MaxSound : 32768 MaxSound : 32768 MaxSound : 32768 MaxSound : 32768 MaxSound : 32768 MaxSound : 32768 MaxSound : 32768 MaxSound : 0 MaxSound : 32768 MaxSound : 32768 –