SoundPlayer and MemoryStream in C# - c#

I build a sample program that select a wav file, then you can play the selected file with 2x speed Or 4x speed
the code of the previous app is :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace PlayWave
{
public partial class Form1 : Form
{
private byte[] B;
private OpenFileDialog open;
public Form1()
{
open = new OpenFileDialog();
open.Filter = "Wav Sound File (*.Wav)|*.wav";
InitializeComponent();
}
private void SelectFile_Click(object sender, EventArgs e)
{
if (!(open.ShowDialog() == DialogResult.OK))
{
return;
}
}
private void twoX_Click(object sender, EventArgs e)
{
B = File.ReadAllBytes(open.FileName);
int samplerate = BitConverter.ToInt32(B, 24) * 2;
Array.Copy(BitConverter.GetBytes(samplerate), 0, B, 24, 4);
using (System.Media.SoundPlayer SP = new System.Media.SoundPlayer(new MemoryStream(B)))
{
SP.Play();
}
}
private void fourX_Click(object sender, EventArgs e)
{
B = File.ReadAllBytes(open.FileName);
int samplerate = BitConverter.ToInt32(B, 24) * 4;
Array.Copy(BitConverter.GetBytes(samplerate), 0, B, 24, 4);
using (System.Media.SoundPlayer SP = new System.Media.SoundPlayer(new MemoryStream(B)))
{
SP.Play();
}
}
}
}
above, I changed the value of (25,26,27,28) bytes of file which represent the sample rate of wave file then save the changes and play the file using System.Media.SoundPlayer and MemoryStream .
my problem is that when I clicked on the button the plays the file in 2x speed over 3 clicks , my program stop and error message appaer ,
can any one tell me why ?

Related

C# - Calling Method 30 times in a second and Creating Screenshots "Bitmaps" - Screen Recorder FPS

This is what I have done and I can get about 20 FPS but I cant increase it to 30 Frames Per second, it begins to lag and memory increases. I dont even know if this is suitable for making screen recording. I am new to C#. I want to make simple screen recorder that can record at least 29 - 30 FPS Stable. I saw the other examples on making screen recorders but they are not recording in 30 FPS. I wan to be able to adjust the FPS. What is the best way to do it? Thanks.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
namespace ScreenRecorder1
{
public partial class Form1 : Form
{
// Recording Size
Size CaptureSize = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
// Capture Thread 1
Thread captureThread1;
int count_FPS = 0;
public Form1()
{
InitializeComponent();
}
//FPS:::::::::::::::::::::START:::::::
//Timer FPS - Display
System.Windows.Forms.Timer FPS_TimerSec;
// FPS - Timer Settings
private void FPS_TimerSec_Settings()
{
FPS_TimerSec = new System.Windows.Forms.Timer();
FPS_TimerSec.Interval = 1000;
FPS_TimerSec.Tick += new EventHandler(FPS_TimerSec_Tick);
FPS_TimerSec.Enabled = true;
FPS_TimerSec.Start();
}
// FPS -Timer - Tick
void FPS_TimerSec_Tick(object sender, EventArgs e)
{
current_fps_label.Text = count_FPS.ToString(); // Display FPS
count_FPS = 0;
}
//FPS:::::::::::::::::::::END:::::::
// Load
private void Form1_Load(object sender, EventArgs e)
{
// Timer
FPS_TimerSec_Settings();
// Capture - Thread
captureThread1 = new Thread(Record12);
captureThread1.IsBackground = true;
captureThread1.Start();
}
// Aborts the Thread On Form Close // Stops Crashing on Form CLose
protected override void OnClosing(CancelEventArgs e)
{
if(captureThread1.IsAlive)
{
captureThread1.Abort();
}
base.OnClosing(e);
}
public void Record12()
{
while(true)
{
Task.Delay(40).Wait();
Task.Run(() =>
{
count_FPS++;
CaptureImage();
});
}
}
private void CaptureImage()
{
using( Bitmap b = new Bitmap(CaptureSize.Width, CaptureSize.Height))
{
using (Graphics g = Graphics.FromImage(b))
{
g.CopyFromScreen(0, 0, 0, 0, CaptureSize, CopyPixelOperation.SourceCopy);
}
Invoke(new Action(() =>
{
if (Player_pictureBox.BackgroundImage != null)
{
Player_pictureBox.BackgroundImage.Dispose();
}
Player_pictureBox.BackgroundImage = b.Clone(
new Rectangle(0, 0, b.Width, b.Height),
System.Drawing.Imaging.PixelFormat.DontCare);
Player_pictureBox.BackgroundImageLayout = ImageLayout.Stretch;
//Player_pictureBox.BackgroundImage = b;
}));
}
}
}
}
UPDATE:
Image1
It runs ok on 20FPS but If I lower the sleep time to 10 "Task.Delay(10).Wait();". The whole OS is slow now and FPS are not Increased.
Image 2

Audiofiles are played with wrong speed

I am using NAudio in a C#-Application and my problem is, that the playback speed depends on the sampling rate. I used two Wav files that contain a 1000Hz sin wave with either Fs = 44100Hz and Fs = 88200 Hz. I checked the output signal of my soundcard with an oscilloscope. It turns out that my file with Fs = 44100 is over after half the expected time, whereas the output frequency is doubled (2kHz). When using the files in other players (e.g. windows media player, audacity) everything looks fine. When debugging I looked into the waveformat of these files and everything looked fine as well. I also varied the bit resolution resulting in no difference. I am not sure if i am just missing out of something.
I use this in another program where this problem first occured. Therefore I made a small rudimentary programm to see if I already made a mistake in my bigger application, the same problem exists there aswell.
It would be really great and highly appreciated, if someone could help me.
Kind regards
Leo
using System;
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;
using NAudio.Wave;
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
AsioOut asioOut;
AudioFileReader afr4;
AudioFileReader afr8;
AudioFileReader afr0;
MixingWaveProvider32 mwp;
int playingID = 0;
int channelID;
Boolean audioplaying = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
asioOut = new AsioOut();
afr4 = new AudioFileReader("../wavs/sin1000Hz_1.75s_16bit_44100Hz_ramp50ms.wav");
afr8 = new AudioFileReader("../wavs/sin1000Hz_1.75s_16bit_88200Hz_ramp50ms.wav");
afr0 = new AudioFileReader("../wavs/sin14607Hz_180sec_20msRamp_fs96000_24bit_mono_doppelt.wav");
mwp = new MixingWaveProvider32();
afr4.Volume = 1.0f;
afr8.Volume = 1.0f;
for (int i = 0; i < asioOut.DriverOutputChannelCount; i++) {
Console.WriteLine(i + ": " + asioOut.AsioOutputChannelName(i));
if (asioOut.AsioOutputChannelName(i).Equals("Analog 3 (1)")) {
channelID = i;
}
}
asioOut.ChannelOffset = channelID;
asioOut.Init(mwp);
asioOut.PlaybackStopped += OnPlaybackStopped;
}
//a button to play the Fs = 44100Hz File
private void button1_Click(object sender, EventArgs e)
{
if (audioplaying == false) {
mwp.AddInputStream(afr4);
afr4.Position = 0;
audioplaying = true;
playingID = 4;
asioOut.Play();
}
}
//a button to play the Fs = 88200Hz File
private void button2_Click(object sender, EventArgs e)
{
if (audioplaying == false) {
mwp.AddInputStream(afr8);
afr8.Position = 0;
audioplaying = true;
playingID = 8;
asioOut.Play();
}
}
//a button to play just another audiofile
private void button4_Click(object sender, EventArgs e)
{
if (audioplaying == false) {
mwp.AddInputStream(afr0);
afr0.Position = 0;
audioplaying = true;
playingID = 0;
asioOut.Play();
}
}
//after playback every Input gets removed again to setup for new playback
protected virtual void OnPlaybackStopped(object sender, EventArgs e) {
if (playingID == 4) {
mwp.RemoveInputStream(afr4);
} else if (playingID == 8) {
mwp.RemoveInputStream(afr8);
} else {
mwp.RemoveInputStream(afr0);
}
audioplaying = false;
}
private void button3_Click(object sender, EventArgs e)
{
asioOut.Stop();
}
}
}
You can't use MixingWaveProvider32 to mix together streams with different WaveFormat. You need to pick a single WaveFormat and pass that into the constructor. You should then only add items that have that WaveFormat although MixingWaveProvider32 isn't enforcing that when you only have one item at a time like you are doing

How can I display an image embedded in my program using the value from a random number generator?

I'm trying to build a Russian Roulette style program where you click a button and it randomly selects one of 25 images to display on screen but I can't seem to figure out how to call the images using the generator.
It works fine when I select an image manually, as seen in my code below, but anything else seems to return an error.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Timers;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using System.Security.Cryptography;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void label_click(object sender, EventArgs e)
{
Close();
}
int mouseX = 0, mouseY = 0;
bool mouseDown;
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
private void GOBUTN_Paint(object sender, PaintEventArgs e)
{
}
//Sharing is caring: Communism goes here
private System.Windows.Forms.Timer timtim;
int rand0;
PictureBox Rooskie = new PictureBox();
Label test = new Label();
Random rando = new Random();
List<int> duplicheck = new List<int>();
private void boopthesnoot(object sender, EventArgs e)
{
dingding:
//Hell yeah, random numbers here
rand0 = rando.Next(1, 26);
/*string combowombo = string.Join(", ", duplicheck.ToArray());
test.Text = combowombo;
test.Font = new Font("Calibri", 20);
Controls.Add(test);
test.Location = new Point(0, 200);
test.Height = 1000;
test.Width = 1000;*/
if(duplicheck.Contains(rand0))
{
goto dingding;
}
else
{
GOBUTTON.Hide();
pictureBox1.Hide();
pictureBox2.Hide();
//Fuckin image code goes here my dood
Rooskie.Width = 1160;
Rooskie.Height = 620;
Bitmap image = new Bitmap(WindowsFormsApp1.Properties.Resources._1);
Rooskie.Dock = DockStyle.Fill;
Rooskie.Image = (Image)image;
Controls.Add(Rooskie);
Rooskie.SizeMode = PictureBoxSizeMode.CenterImage;
//Aww shit, it's that timer time
timtim = new System.Windows.Forms.Timer();
timtim.Tick += new EventHandler(clockfinish);
timtim.Interval = 3000;
timtim.Start();
duplicheck.Add(rand0);
if (duplicheck.Count == 25)
{
duplicheck = new List<int>();
}
}
}
private void clockfinish(object sender, EventArgs e)
{
//CEASE THE TIMER AND GIVE ME BACK MY BUTTON
Rooskie.Image = null;
timtim.Stop();
GOBUTTON.Show();
pictureBox1.Show();
pictureBox2.Show();
}
The expected result is when the user presses the button it calls up the image without having to load it from a folder.

C# label string to int conversion error

I am making a very small RPG game in C# to practice some skill (and to have fun!). I have gotten pretty far with the images, buttons and such.
My issue is that I am being thrown an error when trying to convert my label strings into integers to be compared for my attackingPhase() method.
Here is my code and a screenshot of the error.
I believe my code is correct but I can not figure out as to why the error is being thrown.
Thank you for all help.
using System;
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 RPG
{
public partial class Form2 : Form
{
private Form1 mainForm = null;
public Form2(Form callingForm)
{
mainForm = callingForm as Form1;
InitializeComponent();
pictureBox1.Image = mainForm.MyPictureBoxEnemy.Image;
pictureBox2.Image = mainForm.MyPictureBoxHero.Image;
lbl_Health_Value_Enemy.Text = "100";
lbl_Health_Value_Hero.Text = "100";
}
public void attackingPhase()
{
Random rnd = new Random();
int enemy_damage = rnd.Next(1, 25);
int hero_damage = rnd.Next(2, 15);
var enemyHealth = Convert.ToInt32(lbl_Health_Value_Enemy);
var heroHealth = Convert.ToInt32(lbl_Health_Value_Hero);
if((enemyHealth & heroHealth) > 0)
{
enemyHealth = enemyHealth - enemy_damage;
heroHealth = heroHealth - hero_damage;
} else
{
MessageBox.Show("DEAD");
}
lbl_Health_Value_Enemy.Text = enemyHealth.ToString();
lbl_Health_Value_Hero.Text = heroHealth.ToString();
}
private void btnAttack_Click(object sender, EventArgs e)
{
attackingPhase();
}
}
}
You need to convert the Text property of a label,
var enemyHealth = Convert.ToInt32(lbl_Health_value_Enemy.Text);
var heroHealth = Convert.ToInt32(lbl_Health_Value_Hero.Text);

How can I send Numpad Keys through my program

I'm just trying to create a program that presses Numpad 0 in the program, every few set seconds. This is what I have so far.
using System;
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 WindowsFormsApplication2
{
public partial class Form1 : Form
{
int enabled = 0;
public Form1()
{
InitializeComponent();
}
private void Start_Click(object sender, EventArgs e)
{
if (enabled == 0)
{
Start.Text = "Stop";
Timer.Enabled = true;
enabled = 1;
}
else
{
Start.Text = "Start";
Timer.Enabled = false;
enabled = 0;
label2.Text = "0";
}
}
private void Timer_Tick(object sender, EventArgs e)
{
SendKeys.Send("{NumpadIns}");
label2.Text = Convert.ToString(Convert.ToInt32(label2.Text) + 1);
}
}
}
I have tried this so far
{NumpadIns}
{NumIns}
{Num0}
{INS}
Nothing seems to work, the program I'm using with it is bound to Num Zero so it has to be Num Zero and not 0 on the top row, or Insert. Thanks (Yes I have googled but for some reason this is really hard to find).
From my experience, you should you some wrappers like Input Simulator. It is easy to use and have many pre-defined enums so you do not need to pass String argument.

Categories

Resources