[AUSoundTriggeredPlayingSoundMemoryBased] fix rms calculations. pcm data available as int16 not int32

This commit is contained in:
Rustam Zaitov 2015-06-17 23:19:51 +03:00
Родитель afa6c2442b
Коммит 6df02da5bf
2 изменённых файлов: 39 добавлений и 23 удалений

Просмотреть файл

@ -14,7 +14,7 @@ namespace AUSoundTriggeredPlayingSoundMemoryBased
{
const float PlayDurarion = 0.5f;
const int FramesToPlay = (int) (SampleRate * PlayDurarion);
const int Threshold = 100;
const int Threshold = 30;
const int SampleRate = 44100;
readonly CFUrl url;
@ -24,21 +24,19 @@ namespace AUSoundTriggeredPlayingSoundMemoryBased
AudioBuffers buffer;
AudioStreamBasicDescription srcFormat;
AudioStreamBasicDescription dstFormat;
long totalFrames;
uint currentFrame;
int numberOfChannels;
int triggered;
public long TotalFrames { get; private set; }
public long CurrentPosition
long currentFrame;
public long CurrentFrame
{
set
{
long frame = value;
frame = Math.Min(frame, totalFrames);
frame = Math.Max(frame, 0);
currentFrame = (uint)frame;
currentFrame = frame % TotalFrames;
}
get
{
@ -81,16 +79,37 @@ namespace AUSoundTriggeredPlayingSoundMemoryBased
// Getting signal level and trigger detection
// https://en.wikipedia.org/wiki/Root_mean_square
double rms = 0;
unsafe {
var lPtr = (int*)(void*)outL;
for (int i = 0; i < numberFrames; i++)
rms += (*lPtr) * (*lPtr);
}
rms = Math.Sqrt (rms / numberFrames);
SignalLevel = rms;
AudioBuffer pBuffer = data [0];
Int16[] pcm = new Int16[numberFrames];
Marshal.Copy (pBuffer.Data, pcm, 0, (int)numberFrames);
if (triggered <= 0 && rms > Threshold)
float rms = 0;
for (int j = 0; j < numberFrames; j++) {
float v = pcm [j];
rms += (v * v) / numberFrames;
}
rms = (float)Math.Sqrt (rms);
SignalLevel = rms;
}
// double averageSqrSum = 0;
// unsafe {
// var lPtr = (int*)(void*)outL;
// for (int i = 0; i < numberFrames; i++) {
// double value = *(lPtr + i);
// Console.WriteLine (value);
// averageSqrSum += value * value / numberFrames;
// }
// }
// SignalLevel = Math.Sqrt (averageSqrSum);
// Console.WriteLine ("SignalLevel: {0}", SignalLevel);
// Console.WriteLine ("numberFrames: {0}", numberFrames);
// Console.WriteLine ("-------");
if (triggered <= 0 && SignalLevel > Threshold)
triggered = FramesToPlay;
// playing sound
@ -105,10 +124,7 @@ namespace AUSoundTriggeredPlayingSoundMemoryBased
var buf0 = (int*)buffer [0].Data;
var buf1 = (int*)buffer [numberOfChannels - 1].Data;
if (currentFrame >= totalFrames)
currentFrame = 0;
++currentFrame;
++CurrentFrame;
*outLPtr++ = buf0 [currentFrame];
*outRPtr++ = buf1 [currentFrame];
} else {
@ -134,20 +150,20 @@ namespace AUSoundTriggeredPlayingSoundMemoryBased
extAudioFile.ClientDataFormat = dstFormat;
// getting total frame
totalFrames = extAudioFile.FileLengthFrames;
TotalFrames = extAudioFile.FileLengthFrames;
// Allocating AudioBufferList
buffer = new AudioBuffers(srcFormat.ChannelsPerFrame);
for (int i = 0; i < buffer.Count; ++i)
{
int size = (int)(sizeof(int) * totalFrames);
int size = (int)(sizeof(int) * TotalFrames);
buffer.SetData(i, Marshal.AllocHGlobal(size), size);
}
numberOfChannels = srcFormat.ChannelsPerFrame;
// Reading all frame into the buffer
ExtAudioFileError status;
extAudioFile.Read((uint)totalFrames, buffer, out status);
extAudioFile.Read((uint)TotalFrames, buffer, out status);
if (status != ExtAudioFileError.OK)
throw new ApplicationException();
}

Просмотреть файл

@ -30,7 +30,7 @@ namespace AUSoundTriggeredPlayingSoundMemoryBased
timer = NSTimer.CreateRepeatingTimer (TimeSpan.FromMilliseconds (100),
_ => {
if (isTimerAvailable) {
long pos = player.CurrentPosition;
long pos = player.CurrentFrame;
_slider.Value = pos;
_signalLevelLabel.Text = player.SignalLevel.ToString ("0.00E0");
}
@ -43,7 +43,7 @@ namespace AUSoundTriggeredPlayingSoundMemoryBased
void OnSliderValueChanged(object sender, EventArgs e)
{
isTimerAvailable = false;
player.CurrentPosition = (long)_slider.Value;
player.CurrentFrame = (long)_slider.Value;
isTimerAvailable = true;
}
}