forked from microsoft/psi-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainWindow.cs
More file actions
116 lines (98 loc) · 4.46 KB
/
MainWindow.cs
File metadata and controls
116 lines (98 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
namespace Microsoft.Psi.Samples.LinuxWebcamWithAudioSample
{
using System;
using System.IO;
using System.Reflection;
using Gdk;
using Microsoft.Psi;
using Microsoft.Psi.Audio;
using Microsoft.Psi.Imaging;
using Microsoft.Psi.Media;
/// <summary>
/// Webcam with audio sample program.
/// </summary>
public class MainWindow : Gtk.Window
{
private Pipeline pipeline;
private Gtk.Image displayImage;
private Gtk.Label displayText;
private Gtk.LevelBar displayLevel;
private byte[] imageData = new byte[640 * 480 * 3];
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow"/> class.
/// </summary>
public MainWindow()
: base("Webcam with Audio Sample")
{
// create the window widgets from the MainWindow.xml resource using the builder
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Microsoft.Psi.Samples.LinuxWebcamWithAudioSample.MainWindow.xml");
using StreamReader reader = new StreamReader(stream);
var builder = new Gtk.Builder();
builder.AddFromString(reader.ReadToEnd());
this.Add((Gtk.Widget)builder.GetObject("root"));
// get the widgets which we will modify
this.displayImage = (Gtk.Image)builder.GetObject("image");
this.displayText = (Gtk.Label)builder.GetObject("value");
this.displayLevel = (Gtk.LevelBar)builder.GetObject("level");
// window event handlers
this.Shown += this.MainWindow_Shown;
this.DeleteEvent += this.MainWindow_DeleteEvent;
}
private void MainWindow_Shown(object sender, EventArgs e)
{
// Create the \psi pipeline
this.pipeline = Pipeline.Create();
// Create the webcam component
var webcam = new MediaCapture(this.pipeline, 640, 480, "/dev/video0", PixelFormatId.YUYV);
// Create the audio capture component
var audio = new AudioCapture(this.pipeline, new AudioCaptureConfiguration { DeviceName = "plughw:0,0", Format = WaveFormat.Create16kHz1Channel16BitPcm() });
// Create an acoustic features extractor component and pipe the audio to it
var acousticFeatures = new AcousticFeaturesExtractor(this.pipeline);
audio.PipeTo(acousticFeatures);
// Fuse the webcam images with the audio log energy level
var webcamWithAudioEnergy = webcam.Join(acousticFeatures.LogEnergy, RelativeTimeInterval.Past());
// Overlay the audio energy on the webcam image and display it in the window.
// The "Do" operator is executed on each fused webcam and audio energy sample.
webcamWithAudioEnergy.Do(
frame =>
{
// Update the window with the latest frame
this.DrawFrame(frame);
},
DeliveryPolicy.LatestMessage);
// Start the pipeline running
this.pipeline.RunAsync();
}
private void DrawFrame((Shared<Image> Image, float AudioLevel) frame)
{
// copy the frame image to the pixel buffer
var pixbuf = this.ImageToPixbuf(frame.Image);
// clamp level to between 0 and 20
var audioLevel = frame.AudioLevel < 0 ? 0 : frame.AudioLevel > 20 ? 20 : frame.AudioLevel;
// redraw on the UI thread
Gtk.Application.Invoke(
(sender, e) =>
{
this.displayImage.Pixbuf = pixbuf;
this.displayLevel.Value = audioLevel;
this.displayText.Text = audioLevel.ToString("0.0");
});
}
private Pixbuf ImageToPixbuf(Shared<Image> image)
{
var length = image.Resource.Stride * image.Resource.Height;
if (this.imageData.Length != length)
{
this.imageData = new byte[length];
}
image.Resource.CopyTo(this.imageData);
return new Pixbuf(this.imageData, false, 8, image.Resource.Width, image.Resource.Height, image.Resource.Stride);
}
private void MainWindow_DeleteEvent(object o, Gtk.DeleteEventArgs args)
{
this.pipeline.Dispose();
}
}
}