Kinect V2 - Simple Sound Detection C++
This is a very simple post showing an implementation of the detection of a sound, any sound above a threshold, using the Kinect V2 SDK. The sample is written as a C++ XAML Windows Store app. The code uses the usual pattern for retrieving data from the Kinect via the SDK; that is,
Get Sensor
Choose Datasource
Open a Reader on the DataSource
Subscribe to the FrameArrived event on the Reader
Open the Sensor
This looks like this:
- void MainPage::OnLoaded(Platform::Object ^sender, Windows::UI::Xaml::RoutedEventArgs ^e)
- {
- _kinect = KinectSensor::GetDefault();
- auto audioSource = _kinect->AudioSource;
- // Allocate byte array to hold the audio data
- _audioBuffer = ref new Array<byte>(audioSource->SubFrameLengthInBytes);
- _reader = audioSource->OpenReader();
- _reader->FrameArrived += ref new Windows::Foundation::TypedEventHandler<WindowsPreview::Kinect::AudioBeamFrameReader ^, WindowsPreview::Kinect::AudioBeamFrameArrivedEventArgs ^>(this, &MainPage::OnFrameArrived);
- _kinect->Open();
- }
The the FrameArrived handler goes something like this:
Get BeamFrame Collection
GetBeamFrame Collection first member and iterate over the SubFrames within
For each valid SubFrame copy out the Audio data
Process the audio data
- void MainPage::OnFrameArrived(WindowsPreview::Kinect::AudioBeamFrameReader ^sender, WindowsPreview::Kinect::AudioBeamFrameArrivedEventArgs ^args)
- {
- auto beamCollection = args->FrameReference->AcquireBeamFrames();
- if (beamCollection == nullptr)
- return;
- if (beamCollection->Size < 1)
- return;
- for (auto subFrame : beamCollection->GetAt(0)->SubFrames)
- {
- if (subFrame == nullptr)
- continue;
- // Continue until timeout exceeded
- if (_lastDetected.Duration != 0.0 && (subFrame->RelativeTime.Duration < _lastDetected.Duration + TIMEOUT))
- continue;
- subFrame->CopyFrameDataToArray(_audioBuffer);
- double sum = 0;
- int stride = sizeof(float);
- float sq = 0.0f;
- int sampleCounter = 0;
- // Loop over audio data bytes...
- for (int i = 0; i < _audioBuffer->Length; i += stride)
- {
- memcpy(&sq, &_audioBuffer[i], sizeof(float));
- sum += sq * sq;
- sampleCounter++;
- if (sampleCounter < 40)
- continue;
- float energy = (float) (10.0 * log10(sum / sampleCounter));
- sampleCounter = sum = 0;
- if (energy > ENERGY_THRESHOLD)
- {
- _lastDetected = subFrame->RelativeTime;
- // Sound detected!! Do Stuff....
- break;
- }
- }
- }
- }
The sample is here https://github.com/peted70/kinectv2-detectsound.git
Comments