Replay a BufferedWaveProvider - c#

I use NAudio to record datas from microphone, then i need to playback audio without writing a wav file yet.
Play / Pause / Stop work well, but how can I set back the position to the beginning of bwp and play back from start the audio.
I can't write a wav file yet, because I need to play back the file, navigate throught it with a slider, then erase the end of buffer with new recorded datas, then save the modified file.
private void btn_Start_Click(object sender, EventArgs e)
{
if (sourceList.SelectedItems.Count == 0)
return;
int deviceNumber = sourceList.SelectedItems[0].Index;
wo = new WaveOutEvent();
wi = new WaveIn();
wi.DeviceNumber = deviceNumber;
wi.WaveFormat = new WaveFormat(44100, WaveIn.GetCapabilities(deviceNumber).Channels);
wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable);
bwp = new BufferedWaveProvider(wi.WaveFormat);
bwp.BufferDuration = new TimeSpan(1, 0, 0);
bwp.DiscardOnBufferOverflow = false;
wi.StartRecording();
}
private void wi_DataAvailable(object sender, WaveInEventArgs e)
{
bwp.AddSamples(e.Buffer, 0, e.BytesRecorded);
}
private void btn_Stop_Click(object sender, EventArgs e)
{
wi.StopRecording();
wo.Init(bwp);
}
private void btn_InitWaveOut_Click(object sender, EventArgs e)
{
wo.Play();
}
private void btn_StopWaveOut_Click(object sender, EventArgs e)
{
wo.Stop();
}
private void btn_PauseWaveOut_Click(object sender, EventArgs e)
{
wo.Pause();
}

The BufferedWaveProvider is not designed to support repositioning. If you want that you should make your own IWaveProvider derived class that holds onto all bytes received to allow repositioning. Obviously you'd want to be careful about how much memory you use up as audio data can grow quite large over time.

Related

How can i add links to wpf xmal design by run time code?

I can't figure out how the whole thing is built. Do i need to add each link by my self manually ? And if i have 100 links ?
This is a screenshot of what i see in the xmal file
But maybe i can add this links from the code it self ?
The code is long so i will not add it to here.
I got the project from here:
Background File Downloader
If i want to add to the downloader my own links ?
I see in the DownloaderDemo code this part that add the links:
// Get the contents of the rich text box
string rtbContents = new TextRange(rtbPaths.Document.ContentStart, rtbPaths.Document.ContentEnd).Text;
foreach (string line in rtbContents.Split('\n'))
{
String trimmedLine = line.Trim(' ', '\r');
if (trimmedLine.Length > 0)
{
// If the line is not empty, assume it's a valid url and add it to the files list
// Note: You could check if the url is valid before adding it, and probably should do this is a real application
downloader.Files.Add(new FileDownloader.FileInfo(trimmedLine));
}
}
But i don't understand what richTextBox ? I guess it's in the design in the DownloaderDemo.xaml
Still if i want to add my own links to download files ?
This is DownloaderDemo.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace FileDownloaderApp
{
/// <summary>Interaction logic for DownloaderDemo.xaml</summary>
public partial class DownloaderDemo : Window
{
// Creating a new instance of a FileDownloader
private FileDownloader downloader = new FileDownloader();
public DownloaderDemo()
{
InitializeComponent();
CommandBindings.Add(new CommandBinding(ApplicationCommands.Close,
new ExecutedRoutedEventHandler(delegate(object sender, ExecutedRoutedEventArgs args) { this.Close(); })));
downloader.StateChanged += new EventHandler(downloader_StateChanged);
downloader.CalculatingFileSize += new FileDownloader.CalculatingFileSizeEventHandler(downloader_CalculationFileSize);
downloader.ProgressChanged += new EventHandler(downloader_ProgressChanged);
downloader.FileDownloadAttempting += new EventHandler(downloader_FileDownloadAttempting);
downloader.FileDownloadStarted += new EventHandler(downloader_FileDownloadStarted);
downloader.Completed += new EventHandler(downloader_Completed);
downloader.CancelRequested += new EventHandler(downloader_CancelRequested);
downloader.DeletingFilesAfterCancel += new EventHandler(downloader_DeletingFilesAfterCancel);
downloader.Canceled += new EventHandler(downloader_Canceled);
}
public void DragWindow(object sender, MouseButtonEventArgs args)
{
DragMove();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.Height -= 30;
}
// A simple implementation of setting the directory path, adding files from a textbox and starting the download
private void btnStart_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog openFolderDialog = new System.Windows.Forms.FolderBrowserDialog();
if (openFolderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// Set the path to the local directory where the files will be downloaded to
downloader.LocalDirectory = openFolderDialog.SelectedPath;
// Clear the current list of files (in case it's not the first download)
downloader.Files.Clear();
// Get the contents of the rich text box
string rtbContents = new TextRange(rtbPaths.Document.ContentStart, rtbPaths.Document.ContentEnd).Text;
foreach (string line in rtbContents.Split('\n'))
{
String trimmedLine = line.Trim(' ', '\r');
if (trimmedLine.Length > 0)
{
// If the line is not empty, assume it's a valid url and add it to the files list
// Note: You could check if the url is valid before adding it, and probably should do this is a real application
downloader.Files.Add(new FileDownloader.FileInfo(trimmedLine));
}
}
// Start the downloader
downloader.Start();
}
}
private void btnPause_Click(object sender, RoutedEventArgs e)
{
// Pause the downloader
downloader.Pause();
}
private void btnResume_Click(object sender, RoutedEventArgs e)
{
// Resume the downloader
downloader.Resume();
}
private void btnStop_Click(object sender, RoutedEventArgs e)
{
// Stop the downloader
// Note: This will not be instantantanious - the current requests need to be closed down, and the downloaded files need to be deleted
downloader.Stop();
}
// This event is fired every time the paused or busy state is changed, and used here to set the controls of the interface
// This makes it enuivalent to a void handling both downloader.IsBusyChanged and downloader.IsPausedChanged
private void downloader_StateChanged(object sender, EventArgs e)
{
// Setting the buttons
btnStart.IsEnabled = downloader.CanStart;
btnStop.IsEnabled = downloader.CanStop;
btnPause.IsEnabled = downloader.CanPause;
btnResume.IsEnabled = downloader.CanResume;
// Enabling or disabling the setting controls
rtbPaths.IsReadOnly = downloader.IsBusy;
cbUseProgress.IsEnabled = !downloader.IsBusy;
}
// Show the progress of file size calculation
// Note that these events will only occur when the total file size is calculated in advance, in other words when the SupportsProgress is set to true
private void downloader_CalculationFileSize(object sender, Int32 fileNr)
{
lblStatus.Content = String.Format("Calculating file sizes - file {0} of {1}", fileNr, downloader.Files.Count);
}
// Occurs every time of block of data has been downloaded, and can be used to display the progress with
// Note that you can also create a timer, and display the progress every certain interval
// Also note that the progress properties return a size in bytes, which is not really user friendly to display
// The FileDownloader class provides static functions to format these byte amounts to a more readible format, either in binary or decimal notation
private void downloader_ProgressChanged(object sender, EventArgs e)
{
pBarFileProgress.Value = downloader.CurrentFilePercentage();
lblFileProgress.Content = String.Format("Downloaded {0} of {1} ({2}%)", FileDownloader.FormatSizeBinary(downloader.CurrentFileProgress), FileDownloader.FormatSizeBinary(downloader.CurrentFileSize), downloader.CurrentFilePercentage()) + String.Format(" - {0}/s", FileDownloader.FormatSizeBinary(downloader.DownloadSpeed));
if (downloader.SupportsProgress)
{
pBarTotalProgress.Value = downloader.TotalPercentage();
lblTotalProgress.Content = String.Format("Downloaded {0} of {1} ({2}%)", FileDownloader.FormatSizeBinary(downloader.TotalProgress), FileDownloader.FormatSizeBinary(downloader.TotalSize), downloader.TotalPercentage());
}
}
// This will be shown when the request for the file is made, before the download starts (or fails)
private void downloader_FileDownloadAttempting(object sender, EventArgs e)
{
lblStatus.Content = String.Format("Preparing {0}", downloader.CurrentFile.Path);
}
// Display of the file info after the download started
private void downloader_FileDownloadStarted(object sender, EventArgs e)
{
lblStatus.Content = String.Format("Downloading {0}", downloader.CurrentFile.Path);
lblFileSize.Content = String.Format("File size: {0}", FileDownloader.FormatSizeBinary(downloader.CurrentFileSize));
lblSavingTo.Content = String.Format("Saving to {0}\\{1}", downloader.LocalDirectory, downloader.CurrentFile.Name);
}
// Display of a completion message, showing the amount of files that has been downloaded.
// Note, this does not hold into account any possible failed file downloads
private void downloader_Completed(object sender, EventArgs e)
{
lblStatus.Content = String.Format("Download complete, downloaded {0} files.", downloader.Files.Count);
}
// Show a message that the downloads are being canceled - all files downloaded will be deleted and the current ones will be aborted
private void downloader_CancelRequested(object sender, EventArgs e)
{
lblStatus.Content = "Canceling downloads...";
}
// Show a message that the downloads are being canceled - all files downloaded will be deleted and the current ones will be aborted
private void downloader_DeletingFilesAfterCancel(object sender, EventArgs e)
{
lblStatus.Content = "Canceling downloads - deleting files...";
}
// Show a message saying the downloads have been canceled
private void downloader_Canceled(object sender, EventArgs e)
{
lblStatus.Content = "Download(s) canceled";
pBarFileProgress.Value = 0;
pBarTotalProgress.Value = 0;
lblFileProgress.Content = "-";
lblTotalProgress.Content = "-";
lblFileSize.Content = "-";
lblSavingTo.Content = "-";
}
// Setting the SupportsProgress property - if set to false, no total progress data will be avaible!
private void cbUseProgress_Checked(object sender, RoutedEventArgs e)
{
downloader.SupportsProgress = (Boolean)cbUseProgress.IsChecked;
}
// Setting the DeleteCompletedFilesAfterCancel property - indicates if the completed files should be deleted after cancellation
private void cbDeleteCompletedFiles_Checked(object sender, RoutedEventArgs e)
{
downloader.DeleteCompletedFilesAfterCancel = (Boolean)cbDeleteCompletedFiles.IsChecked;
}
// Close the window when the close button is hit
private void btnClose_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}
You can easily add to the rich text box new download links by creating your own function that takes a new download link path, to append to the text box you do:
richTextBox.AppendText("new string of download link");
You're not sure what rich text box? It is in your .xaml file, it is called rtbPaths. So you could create a new button that executes a dialog box, takes a string and use that string to append to this text box.
It's hard to understand what is being asked here as well, sorry if I got this wrong.

Visual C# - Properties.Settings won't save correctly

I'm making a program that saves the Mouse X and Mouse Y coordinates from a NumericUpDown-Box into Settings.settings so the program launches with the last used values.
Both Input Boxes call the method "saveXY" when "ValueChanged" as seen here
My Problem is: the X coordinates get saved without problems, the Y coordinates don't get saved at all - but the code is the same:
private void Form1_Load(object sender, EventArgs e)
{
movetoX.Value = Settings.Default.mouseX;
movetoY.Value = Settings.Default.mouseY;
}
-
private void saveXY(object sender, EventArgs e)
{
Settings.Default.mouseX = (int)movetoX.Value;
Settings.Default.mouseY = (int)movetoY.Value;
Settings.Default.Save();
}
Theese are my Settings.settings.
The .exe is availeble here.
This article may be useful to you. http://msdn.microsoft.com/en-us/library/aa730869%28v=vs.80%29.aspx
Update 1:
Had to perform a Properties.Settings.Default.Upgrade() and then your saved settings get loaded.
Sample
public Form1()
{
InitializeComponent();
//Load saved settings
this.Location = Properties.Settings.Default.Form1Location;
this.Size = Properties.Settings.Default.Form1Size;
//Allow changes to be implemented
this.StartPosition = FormStartPosition.Manual;
//capture changes
this.LocationChanged += new EventHandler(Form1_LocationChanged);
this.SizeChanged += new EventHandler(Form1_SizeChanged);
//capture the closing form event to save your new settings
this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);
}
void Form1_LocationChanged(object sender, EventArgs e)
{
//Capture the new values
Properties.Settings.Default.Form1Location = this.Location;
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//Capture the new values
Properties.Settings.Default.Form1Size = this.Size;
}
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//you can capture the new values here as well
//save the new values
Properties.Settings.Default.Save();
}
thanks to hamix, its working now
i deleted saveXY and wrote this:
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Settings.Default.mouseX = (int)movetoX.Value;
Settings.Default.mouseY = (int)movetoY.Value;
Settings.Default.Save();
}
it now saves X and Y

Using AFORGE to record the videos in c#

i've try the following way to record the video from the Webcam by 25 Frame-rate per sec for 10sec but when i get the out put video it is of 2sec and the frames are played to fast as compare to the video stream.
The code is as follows.
using System;
using System.Drawing;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Threading;
using AForge.Video.FFMPEG;
namespace AforgeTutorial
{
public partial class Form1 : Form
{
private FilterInfoCollection ListOfCams;
private VideoCaptureDevice SelectedCam; //From where we will take image
System.Timers.Timer tim;
Thread t;
bool isNewFrame = false;
VideoFileWriter writer;
public Form1()
{
InitializeComponent();
tim = new System.Timers.Timer(10000);
tim.Elapsed += new System.Timers.ElapsedEventHandler(tim_Elapsed);
t = new Thread(saveVideo);
}
void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (isRecord)
{
writer.Close();
isRecord = false;
}
}
private void Form1_Load(object sender, EventArgs e)
{
ListOfCams = new FilterInfoCollection(FilterCategory.VideoInputDevice);
if (ListOfCams.Count == 0)
return;
comboBox1.Items.Clear();
foreach (FilterInfo Cam in ListOfCams)
{
comboBox1.Items.Add(Cam.Name);
}
}
private void StopCamera()
{
SelectedCam.SignalToStop();
SelectedCam.Stop();
}
bool isRecord = false;
private void Start_Click(object sender, EventArgs e)
{
if (comboBox1.Text == string.Empty)
return;
SelectedCam = new VideoCaptureDevice(ListOfCams[comboBox1.SelectedIndex].MonikerString);
SelectedCam.NewFrame += new NewFrameEventHandler(SelectedCam_NewFrame);
SelectedCam.Start();
}
Bitmap image;
void SelectedCam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
image = (Bitmap)eventArgs.Frame.Clone();
isNewFrame = true;
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
StopCamera();
}
private void Stop_Click(object sender, EventArgs e)
{
StopCamera();
}
private void btnRecord_Click(object sender, EventArgs e)
{
tim.Start();
if (!isRecord)
{
writer = new VideoFileWriter();
writer.Open(#"C:/code-bude_test_video.mp4", 640, 480, 25, VideoCodec.MPEG4,10000);
}
isRecord = !isRecord;
if (isRecord)
t.Start();
}
void saveVideo()
{
while (isRecord)
{
if (isNewFrame)
{
writer.WriteVideoFrame(image);
isNewFrame = false;
}
}
}
}
}
You have multi-threading issues in your code. You can't write to shared variables like that and expect it to synchronize.
You have three threads: user interface, streaming and saving. (SelectedCam_NewFrame runs in the AForge streaming thread). Make a list of all variables that are accessed in at least two threads (isRecord, isNewFrame, etc) and add proper synchronization.
You can check this very good reference on threading in C#.
Note that even with synchronization, you may miss frames if your writer thread is busy while several images arrive. What you might want to do is collect the frames produced by the camera in a queue and consume that queue in the writer thread. Check the producer/consumer patterns.

SerialPort reading process doesn't work properly in C#

I'm developing an application which communicates with my electronic circuit via Port 4. I can send data from the PC to the circuit without a problem; I then get data back from the circuit. However, when I try to get data from my circuit for the second time, I receive incorrect data from it. Any pointers on how to solve this?
This is C# code:
byte[] Sent_Byte = {1,2,3,4,5,6};
byte[] Received_Byte = new byte[10];
private void button_sendData_Click(object sender, EventArgs e)
{
// I send this data because the circuit is ready to get data
serialPort1.Write("G");
serialPort1.Write(Sent_Byte, 0, 6);
}
private void button_getData_Click(object sender, EventArgs e)
{
// I send this data because the circuit is ready to send data
serialPort1.Write("A");
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
serialPort1.Read(Received_Byte, 0, 10);
}
This is Arduino code:
char Control_OP=0;
char Received_Data[6];
byte Sent_Data[10];
void loop()
{
while(Serial.available())
{
Control_OP = Serial.read(); // determines whether receiving data or sending data
if(Control_OP=='G') // receiving data
{
Number=Serial.readBytes(Received_Data,6);
}
else if(Control_OP=='A') // sending data
{
Serial.write(Sent_Data,10);
}
}
}
I found the solution.
I changed this code
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
serialPort1.Read(Received_Byte, 0, 10);
}
into this one
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
for (int i = 0; i <Received_Byte.Length; i++)
{
Received_Byte[i] = Convert.ToByte(serialPort1.ReadByte());
}
}
Thanks everyone for helping me

Microsoft MediaPlayer Memory Leak winforms

Hello when I play a video on a loop more and more memory is continually gobbled up. When I try to dispose of the MediaPlayer control only some of the memory is freed up.
My program needs to play hundreds / thousands of audios but this is results in my program getting larger and larger and slowing down.
Any ideas?
private void button10_Click(object sender, EventArgs e)
{
addTimer.Tick += addTimer_Tick;
addTimer.Interval = 1000;
addTimer.Start();
}
void addTimer_Tick(object sender, EventArgs e)
{
//axWindowsMediaPlayer1.URL = #"c:\temp\Catching.avi";
if (this.axWindowsMediaPlayer1.currentMedia != null)
{
this.axWindowsMediaPlayer1.Ctlcontrols.stop();
this.axWindowsMediaPlayer1.currentPlaylist.clear();
}
WMPLib.IWMPMedia currentMedia = this.axWindowsMediaPlayer1.newMedia(#"c:\temp\Catching.avi");
this.axWindowsMediaPlayer1.currentMedia = currentMedia;
}
private void button11_Click(object sender, EventArgs e)
{
this.Controls.RemoveByKey("wmp");
axWindowsMediaPlayer1.close();
axWindowsMediaPlayer1.Dispose();
GC.Collect();
}

Categories

Resources