I have written a C# WinForms application. I want to get the data of the sound card in regular intervals. For this, I use the NAudio package. To check if I initialize the objects waveIn and WaveFormat with the correct values (SampleRate, number of channels, number of depth bits), I generated several audio tracks with Audacity. Among others, a square wave that can be heard for 2.5 seconds, then is silent for 2.5 seconds, etc. In the WaveIn_DataAvailable event handler, I paint a rectangle. I would expect it to turn red for 2.5 seconds, then turn black for 2.5 seconds. Unfortunately, the rectangle always flickers red and black when the audio is muted. So there is the problem that I can't test because at the moment of silence (it seems) there are everything but zeros in e.Buffer. Even at the moment of the sound, the rectangle is not ‘permanently’ red. Actually there is always flickering between red and black. What is the problem?
My soundcard is capable of 48 kHz, 24 bit. I don't know the number of channels. If channels refers to stereo or mono, then, of course, channel = 2.
using System;
using System.Windows.Forms;
using NAudio.Wave;
namespace Sound_Capture_Program
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private int DeviceNumber = 0;
private WaveIn waveIn = null;
private void FormMain_Load(object sender, EventArgs e)
{
for (int i = 0; i < WaveIn.DeviceCount; i++)
{
WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(i);
ComboboxDevices.Items.Add(deviceInfo.ProductName);
}
if (ComboboxDevices.Items.Count >= 2)
{
ComboboxDevices.SelectedIndex = 1;
}
}
private void Combobox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ComboboxDevices.SelectedIndex != -1)
{
this.DeviceNumber = ComboboxDevices.SelectedIndex;
}
}
private void ButtonStart_Click(object sender, EventArgs e)
{
int sampleRate = int.Parse(Textbox_SR.Text);
waveIn = new WaveIn()
{
DeviceNumber = this.DeviceNumber,
WaveFormat = new WaveFormat(sampleRate, 24, 1)
};
waveIn.DataAvailable += WaveIn_DataAvailable;
waveIn.StartRecording();
ButtonStart.Enabled = false;
ButtonStop.Enabled = true;
}
private void ButtonStop_Click(object sender, EventArgs e)
{
waveIn.DataAvailable -= WaveIn_DataAvailable;
waveIn.StopRecording();
waveIn.Dispose();
ButtonStart.Enabled = true;
ButtonStop.Enabled = false;
}
private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
{
using (System.Drawing.Graphics g = this.CreateGraphics())
{
//byte redvalue = (byte)(((int)e.Buffer[0] + (int)e.Buffer[1] + (int)e.Buffer[2]) / 3);
System.Drawing.Color color = System.Drawing.Color.FromArgb(e.Buffer[0], 0, 0);
using (System.Drawing.SolidBrush Brush = new System.Drawing.SolidBrush(color))
{
g.FillRectangle(Brush, 250, 150, 20, 20);
}
}
}
private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (waveIn != null)
{
waveIn.DataAvailable -= WaveIn_DataAvailable;
waveIn.StopRecording();
waveIn.Dispose();
}
}
}
}
Audacity
Related
Again, I am asking a question about a USB Printer. This time however, the issue is more on the programming end of the spectrum.
I have a windows forms application in which I generate a receipt, which is then supposed to be sent to the printer. The Following things work: Generating the receipt, Sending the data to the printer.
The data however is only an empty strip of paper. I have the feeling that the Software is ignoring the Panel contents and just sends the empty panel to the printer.
The Sourcecode is as follows:
namespace MakeyMakey
{
public partial class Form1 : Form
{
public void Gridsettings()
{
GVReceipt.ScrollBars = ScrollBars.None;
GVReceipt.RowHeadersVisible = false;
GVReceipt.ColumnCount = 3;
GVReceipt.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
GVReceipt.CellBorderStyle = DataGridViewCellBorderStyle.None;
}
public Form1()
{
InitializeComponent();
pCompanyImage.SizeMode = PictureBoxSizeMode.StretchImage;
Bitmap Logo = new Bitmap(Bitmap.FromFile(#"C:/Users/manue/source/repos/MakeyMakey/MakeyMakey/logo.png"));
pCompanyImage.Image = MakeBW(Logo);
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode("Hier kann so gut wie alles stehen", QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
Bitmap qrCodeImage = qrCode.GetGraphic(20);
pQRCode.Image = qrCodeImage;
panel1.Height = GVProduct.Height + 220;
GVReceipt.Columns.Add("Name", "Name");
GVReceipt.Columns.Add("QTY", "QTY");
GVReceipt.Columns.Add("Price", "Price");
GVReceipt.Columns[0].Width = 50;
GVReceipt.Columns[1].Width = 15;
GVReceipt.Columns[2].Width = 50;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void label4_Click(object sender, EventArgs e)
{
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string[] row = new string[] {txtName.Text, txtQty.Text, txtPrice.Text };
GVReceipt.Rows.Add(row);
GVProduct.Rows.Add(row);
Gridsettings();
Calc();
txtName.Clear();
txtQty.Clear();
txtPrice.Clear();
txtName.Focus();
}
private void GVResize()
{
//MessageBox.Show(GVReceipt.Height.ToString());
GVReceipt.Height = GVReceipt.ColumnHeadersHeight + GVReceipt.RowCount * GVReceipt.Rows[0].Height;
//MessageBox.Show(GVReceipt.Height.ToString());
panel1.Height += GVReceipt.Rows[0].Height;
//MessageBox.Show(panel1.Height.ToString());
GVReceipt.ClearSelection();
Refresh();
}
private void GVReceipt_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
}
private void GVReceipt_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
panel1.Height = 389;
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
public Bitmap MakeBW(Bitmap Map)
{
Bitmap newbmp = new Bitmap(Map.Width, Map.Height); // New image
for (int row = 0; row < Map.Width; row++) // Indicates row number
{
for (int column = 0; column < Map.Height; column++) // Indicate column number
{
var colorValue = Map.GetPixel(row, column); // Get the color pixel
var averageValue = ((int)colorValue.R + (int)colorValue.B + (int)colorValue.G) / 3; // get the average for black and white
newbmp.SetPixel(row, column, Color.FromArgb(averageValue, averageValue, averageValue)); // Set the value to new pixel
}
}
return newbmp;
}
public void Calc()
{
decimal total = 0;
for(int i = 0; i < GVReceipt.RowCount-1; i++)
{
total += Convert.ToDecimal(GVReceipt.Rows[i].Cells[2].Value) * Convert.ToDecimal(GVReceipt.Rows[i].Cells[1].Value);
}
//Console.WriteLine("HELLO");
//MessageBox.Show(total.ToString());
lbltotal.Text = total.ToString() + "€";
Refresh();
GVResize();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Print(panel1);
}
Bitmap MemoryImage;
PrintDocument printdoc1 = new PrintDocument();
PrintPreviewDialog previewdlg = new PrintPreviewDialog();
public void GetPrintArea(Panel pnl)
{
MemoryImage = new Bitmap(pnl.Width, pnl.Height);
Rectangle rect = new Rectangle(0, 0, pnl.Width, pnl.Height);
pnl.DrawToBitmap(MemoryImage, new Rectangle(0, 0, pnl.Width, pnl.Height));
}
public void printdoc1_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawImage(MemoryImage, 0, 0);
}
public void Print(Panel pnl)
{
GetPrintArea(pnl);
printdoc1.PrinterSettings.PrinterName = "Generico";
printdoc1.DefaultPageSettings.PaperSize = new PaperSize("Custom", panel1.Width, panel1.Height);
previewdlg.Document = printdoc1;
previewdlg.ShowDialog();
printdoc1.Print();
}
private void btnPrinter_Click(object sender, EventArgs e)
{
printDocument1.Print();
GVProduct.Rows.Clear();
GVReceipt.Rows.Clear();
Calc();
}
private void GVReceipt_RowsAdded_1(object sender, DataGridViewRowsAddedEventArgs e)
{
//GVResize();
}
}
I have also included two images, one shows what the receipt looks like, the other what the print preview generated.
I'd highy appreciate any help on that topic.
For my school I have to do a little project.
The aim of the project is to do a game which spawns different rectangles and you have to click them.
If you click them you recive points and the rectangle gets replaced with a new one.
And every timer tick the box gets bigger.
We have to use pictureboxes.
Now my question is:
How can I make a detection to indicate a picturebox which colides with the panel-border or with a other picture box.
The problem is, that the picboxes are getting duplicated.
So how can I solve this problem?
This is my code:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BoxClicker
{
public partial class Form1 : Form
{
private Random rndColor = new Random();
private Random rndCreation = new Random();
public Form1()
{
InitializeComponent();
}
private void CreateBox()
{
PictureBox gamebox = new PictureBox();
gamebox.Size = new Size(20, 20);
gamebox.Location = new Point(rndCreation.Next(0, pnlSpiel.Width - 30), rndCreation.Next(0, pnlSpiel.Height - 30));
gamebox.BackColor = Color.FromArgb(rndCreation.Next(0, 255), rndCreation.Next(0, 255), rndCreation.Next(0, 255));
pnlSpiel.Controls.Add(gamebox);
gamebox.Click += pictureBox1_Click;
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < numValues.Value; i++)
{
CreateBox();
}
tmrResize.Start();
txtNotification.Text = "Klicke auf die erscheinenden Boxen um Punkte zu sammeln!";
btnStart.Visible = false;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void pictureBox1_Click(object sender, EventArgs e)
{
CreateBox();
PictureBox gamebox = sender as PictureBox;
int addPoints = gamebox.Width;
txtPoints.Text = (Convert.ToInt32(txtPoints.Text) + addPoints).ToString();
if ((Convert.ToInt32(txtBiggestBox.Text) < addPoints))
{
txtBiggestBox.Text = (Convert.ToString(addPoints));
}
pnlSpiel.Controls.Remove(sender as PictureBox);
}
private void button1_Click_1(object sender, EventArgs e)
{
if (tmrEasterEgg.Enabled)
{
tmrEasterEgg.Stop();
BackColor = Color.LightGray;
}
else
{
tmrEasterEgg.Start();
}
}
private void tmrEasterEgg_Tick(object sender, EventArgs e)
{
Color randomColor = Color.FromArgb(rndColor.Next(256), rndColor.Next(256), rndColor.Next(256));
BackColor = randomColor;
}
private void tmrResize_Tick(object sender, EventArgs e)
{
for (int i = 0; i < pnlSpiel.Controls.Count; i++)
{
PictureBox gamebox = pnlSpiel.Controls[i] as PictureBox;
gamebox.Size = new Size(gamebox.Size.Width + 1, gamebox.Size.Height + 1);
}
}
private void btnReset_Click(object sender, EventArgs e)
{
pnlSpiel.Controls.Clear();
txtNotification.Text = "Das Spiel wurde zurückgesetzt";
txtPoints.Text = "0";
btnStart.Visible = true;
}
}
}
You can have the collision detection in your CreateBox method. And decide whether to add the object or not in there.
Like this:
private void CreateBox()
{
Rectangle bounds = new Rectangle(rndCreation.Next(0, pnlSpiel.Width - 30),
rndCreation.Next(0, pnlSpiel.Height - 30),
20, 20);
bool pBDoIntersect = false;
foreach (Control picturebox in pnlSpiel.Controls)
{
if (bounds.IntersectsWith(picturebox.Bounds))
{
pBDoIntersect = true;
}
}
if (!pBDoIntersect)
{
PictureBox gamebox = new PictureBox();
gamebox.Size = new Size(bounds.Width, bounds.Height);
gamebox.Location = new Point(bounds.X, bounds.Y);
gamebox.BackColor = Color.FromArgb(rndCreation.Next(0, 255), rndCreation.Next(0, 255), rndCreation.Next(0, 255));
pnlSpiel.Controls.Add(PB);
gamebox.Click += pictureBox1_Click;
}
else
{
// spawn in another place?
}
}
I am new in c# and trying to develop Scary Screamer Application. It is an joke windows forms application which is running on the PC and invisible in taskbar.
There is timer running in this application. If system datetime.now.minute = 15
It should play scary sound and show scary picture on the screen. After 1-2 seconds picture should disappear from the screen.
But i am stuck and don't know how to make picture disappear. Any Ideas how to do that?
Below is my code:
namespace screamer2
{
public partial class Form1 : Form
{
SoundPlayer pla = new SoundPlayer(Properties.Resources._3);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.TransparencyKey = this.BackColor;
this.Left = 0;
this.Top = 0;
this.Width = Screen.PrimaryScreen.Bounds.Width/2;
this.Height = Screen.PrimaryScreen.Bounds.Height/2;
this.TopMost = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (DateTime.Now.Minute == 15)
{
BackgroundImage = Properties.Resources._1;
System.Threading.Thread.Sleep(500);
pla.Play();
}
}
}
}
I would propose to set image once in Form1_Load and then control any showing and hiding of window using Form.Opacity variable. I have tested the code below and should work as you wanted.
SoundPlayer pla = new SoundPlayer(Properties.Resources._3);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.TransparencyKey = this.BackColor;
this.Left = 0;
this.Top = 0;
this.Opacity = 0; //This line added
this.Width = Screen.PrimaryScreen.Bounds.Width / 2;
this.Height = Screen.PrimaryScreen.Bounds.Height / 2;
this.BackgroundImage = Properties.Resources._1; //We set the image once here
this.TopMost = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (DateTime.Now.Minute == 15)
{
this.Opacity = 1; //We show the window
System.Threading.Thread.Sleep(500);
pla.Play();
this.Opacity = 0; //We hide the window
}
}
I want to show a pixel in the screen.I use openTk in Vs2010.
this is my code in Windows form application:
private void glControl1_Load(object sender, EventArgs e)
{
OpenTK.Graphics.OpenGL.GL.ClearColor(Color.DeepSkyBlue);
OpenTK.Graphics.OpenGL.GL.Color3(Color.Black);
}
private void glControl1_Paint(object sender, PaintEventArgs e)
{
OpenTK.Graphics.OpenGL.GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit|OpenTK.Graphics.OpenGL.ClearBufferMask.DepthBufferBit);
OpenTK.Graphics.OpenGL.GL.MatrixMode(MatrixMode.Modelview);
OpenTK.Graphics.OpenGL.GL.LoadIdentity();
OpenTK.Graphics.OpenGL.GL.Begin(BeginMode.Points);
OpenTK.Graphics.OpenGL.GL.Vertex3(3,5,9);
OpenTK.Graphics.OpenGL.GL.End();
glControl1.SwapBuffers();
}
when I run my code I just see a Blue screen.I don't know what is wrong!!!
In order to display anything you will need to set the transformation matrices for projection. In your code you are not setting anything which means that the rendering will not have any idea on where to put your point.
I'd suggest looking into some basic tutorial for working with low-level OpenGL. Most of it should be applicable to your scenario.
Take a look at opentk glcontrol-based apps
using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Diagnostics;
namespace GLControlApp
{
public partial class Form1 : Form
{
bool loaded = false;
public Form1()
{
InitializeComponent();
}
Stopwatch sw = new Stopwatch(); // available to all event handlers
private void glControl1_Load(object sender, EventArgs e)
{
loaded = true;
GL.ClearColor(Color.SkyBlue); // Yey! .NET Colors can be used directly!
SetupViewport();
Application.Idle += Application_Idle; // press TAB twice after +=
sw.Start(); // start at application boot
}
void Application_Idle(object sender, EventArgs e)
{
double milliseconds = ComputeTimeSlice();
Accumulate(milliseconds);
Animate(milliseconds);
}
float rotation = 0;
private void Animate(double milliseconds)
{
float deltaRotation = (float)milliseconds / 20.0f;
rotation += deltaRotation;
glControl1.Invalidate();
}
double accumulator = 0;
int idleCounter = 0;
private void Accumulate(double milliseconds)
{
idleCounter++;
accumulator += milliseconds;
if (accumulator > 1000)
{
label1.Text = idleCounter.ToString();
accumulator -= 1000;
idleCounter = 0; // don't forget to reset the counter!
}
}
private double ComputeTimeSlice()
{
sw.Stop();
double timeslice = sw.Elapsed.TotalMilliseconds;
sw.Reset();
sw.Start();
return timeslice;
}
private void SetupViewport()
{
int w = glControl1.Width;
int h = glControl1.Height;
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Ortho(0, w, 0, h, -1, 1); // Bottom-left corner pixel has coordinate (0, 0)
GL.Viewport(0, 0, w, h); // Use all of the glControl painting area
}
private void glControl1_Paint(object sender, PaintEventArgs e)
{
if (!loaded)
return;
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
GL.Translate(x, 0, 0);
if (glControl1.Focused)
GL.Color3(Color.Yellow);
else
GL.Color3(Color.Blue);
GL.Rotate(rotation, Vector3.UnitZ); // OpenTK has this nice Vector3 class!
GL.Begin(BeginMode.Triangles);
GL.Vertex2(10, 20);
GL.Vertex2(100, 20);
GL.Vertex2(100, 50);
GL.End();
glControl1.SwapBuffers();
}
int x = 0;
private void glControl1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
x++;
glControl1.Invalidate();
}
}
private void glControl1_Resize(object sender, EventArgs e)
{
SetupViewport();
glControl1.Invalidate();
}
}
}
I am completely new to video input, and just started working with AForge a few days ago. Working with live video is comfortable, but I need to do something with files for a project now.
Using the Windows Media Video 9 VCM codec, saving has not been a problem. The output file works normally with every player I have, but my program always plays it back at about double the frame rate. This is especially odd since there is never any indication that the frame rate is changed: both the default the video was saved with and the new player indicate that the frame rate is 25 fps.
The only suggestions I have found are to change the frame rate before the video is captured, but this seems to do nothing.
Looking around in the AVIFileVideoSource documentation, I found the FrameIntervalFromSource and FrameInterval properties which, together, should give me the results I am looking for, but I can't get them to work, either. Everything else has been a dead end, and I am out of ideas. Here is the code that I am using to read the file:
public partial class Form1 : Form
{
AVIReader input = new AVIReader();
AVIFileVideoSource source = new AVIFileVideoSource("test.avi");
public Form1()
{
InitializeComponent();
}
public void cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
input.Open("test.avi");
for (int i = 0; i < input.Length; i++)
{
pictureBox1.Image = input.GetNextFrame();
}
source.Stop();
input.Close();
}
private void button1_Click(object sender, EventArgs e)
{
source.NewFrame += new NewFrameEventHandler(cam_NewFrame);
source.Start();
}
private void button2_Click(object sender, EventArgs e)
{
source.Stop();
input.Close();
}
}
Any other suggestions would be greatly appreciated. Thank you for your time.
I found a working solution to the problem by looking into some other areas of the library. In this solution, there were two other classes that I was overlooking: DirectShow, which was already referenced, and Control. Specifically, I needed to use instances of FileVideoSource and VideoSourcePlayer to get the video into something I could work with.
This version is different from the above in that both the read and write functions have been combined into one program. Furthermore, I was in something of a rush to get this done, so it is still quite fragile. Nevertheless, here is my solution:
public partial class Form1 : Form
{
public Bitmap newBitmap;
public VideoCaptureDevice cam = null;
public FilterInfoCollection usbCams;
AVIReader reader = new AVIReader();
AVIWriter writer = new AVIWriter("wmv3");
AVIFileVideoSource source = new AVIFileVideoSource("test.avi");
FileVideoSource normSource = new FileVideoSource("test.avi");
VideoSourcePlayer player = new VideoSourcePlayer();
public Form1()
{
InitializeComponent();
}
public void cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap image = (Bitmap)eventArgs.Frame.Clone();
writer.AddFrame(image);
pictureBox1.Image = image;
}
public void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
newBitmap = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = newBitmap;
}
private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image)
{
videoSourcePlayer1.VideoSource = normSource;
videoSourcePlayer1.GetCurrentVideoFrame();
videoSourcePlayer1.DrawToBitmap(newBitmap,
new Rectangle(0, 0, image.Width, image.Height));
}
private void button1_Click(object sender, EventArgs e)
{
source.NewFrame += new NewFrameEventHandler(video_NewFrame);
source.Start();
videoSourcePlayer1.NewFrame += new AForge.Controls.VideoSourcePlayer.NewFrameHandler(videoSourcePlayer_NewFrame);
videoSourcePlayer1.Start();
}
private void button2_Click(object sender, EventArgs e)
{
if (source.IsRunning == true)
{
source.Stop();
videoSourcePlayer1.Stop();
}
if (cam != null)
{
cam.Stop();
writer.Close();
}
}
private void button3_Click(object sender, EventArgs e)
{
usbCams = new FilterInfoCollection(FilterCategory.VideoInputDevice);
cam = new VideoCaptureDevice(usbCams[0].MonikerString);
cam.DesiredFrameSize = new Size(320, 240);
writer.Open("test.avi", 320, 240);
cam.NewFrame += new NewFrameEventHandler(cam_NewFrame);
cam.DesiredFrameRate = 25;
cam.Start();
}
}
Thank you for reading.