using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using WaveLib;
using GenericGraph;
using System.IO;
using System.Runtime.InteropServices;

namespace HearingAidLab
{
	/// <summary>
	/// Summary description for Chirp.
	/// </summary>
	public class Chirp : System.Windows.Forms.Form
	{
		private System.ComponentModel.IContainer components;

		public Form1 mainmenu;
		private GGraph graph1;
		private GGraph graph2;
		private GGraph graph3;
		private int nSam = 32000;
		public ChirpCal cal;
		public ChirpCal left;
		public ChirpCal right;
		private WaveBuffer b2;
		private WaveBuffer chirp = new WaveBuffer();
		public double dLevel;
		public int nMic;
		public int nMaxInt;
		public double dMaxOut;
		public double dMaxIn;
		public WaveRecorder rec = new WaveRecorder();
		public WaveLib.WavePlayer player = new WavePlayer();
		public ArrayList CalList = new ArrayList();
		private ChirpParams cprms;
		
		#region FormStuff		
		private System.Windows.Forms.Panel panel1;
		private System.Windows.Forms.Panel panel2;
		private System.Windows.Forms.Panel panel3;
		private System.Windows.Forms.TextBox txtTestLevel;
		private System.Windows.Forms.Button btnPlay;
		private System.Windows.Forms.Button btnClosePlayer;
		private System.Windows.Forms.TextBox txtTestFreq;
		private System.Windows.Forms.TextBox tbCurSeg;
		private System.Windows.Forms.ToolBar toolBarChirp;
		private System.Windows.Forms.ImageList imageChirp;
		private System.Windows.Forms.ToolBarButton toolBarLoad;
		private System.Windows.Forms.ToolBarButton toolBarSave;
		private System.Windows.Forms.ToolBarButton toolBarSep;
		private System.Windows.Forms.ToolBarButton toolBarPlay;
		private System.Windows.Forms.ToolBarButton toolBarParams;
		private System.Windows.Forms.StatusBarPanel sbStatus;
		private System.Windows.Forms.StatusBarPanel sbMic;
		private System.Windows.Forms.StatusBarPanel sbRes;
		private System.Windows.Forms.StatusBarPanel sbOut;
		private System.Windows.Forms.StatusBarPanel sbPeak;
		private System.Windows.Forms.StatusBarPanel sbIn;
		private System.Windows.Forms.StatusBar sbChirp;
		private System.Windows.Forms.Label lblCurSeg;
		private System.Windows.Forms.Label lblTestLevel;
		private System.Windows.Forms.ToolBarButton toolBarSep2;
		private System.Windows.Forms.ToolBarButton toolBarLeft;
		private System.Windows.Forms.ToolBarButton toolBarButton3;
		private System.Windows.Forms.ToolBarButton toolBarSep3;
		private System.Windows.Forms.ToolBarButton toolBarTestComplex;
		private System.Windows.Forms.Label lblTestFreq;
		#endregion
		

		public Chirp()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
			this.Closing += new CancelEventHandler(Chirp_Closing);
			lblTestFreq.Visible = false;
			lblTestLevel.Visible = false;
			txtTestFreq.Visible = false;
			txtTestLevel.Visible = false;
			btnPlay.Visible = false;
			this.btnClosePlayer.Visible = false;

			graph1 = new GGraph();
			graph2 = new GGraph();
			graph3 = new GGraph();
			this.WindowState = FormWindowState.Maximized;
			cprms = new ChirpParams();
			ShowStats();
#if !DEBUG
			this.tbCurSeg.Visible = false;
			this.lblCurSeg.Visible = false;
#endif
			
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			mainmenu.Show();
			

			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Chirp));
			this.panel1 = new System.Windows.Forms.Panel();
			this.panel2 = new System.Windows.Forms.Panel();
			this.panel3 = new System.Windows.Forms.Panel();
			this.lblTestLevel = new System.Windows.Forms.Label();
			this.txtTestLevel = new System.Windows.Forms.TextBox();
			this.btnPlay = new System.Windows.Forms.Button();
			this.btnClosePlayer = new System.Windows.Forms.Button();
			this.txtTestFreq = new System.Windows.Forms.TextBox();
			this.lblTestFreq = new System.Windows.Forms.Label();
			this.lblCurSeg = new System.Windows.Forms.Label();
			this.tbCurSeg = new System.Windows.Forms.TextBox();
			this.toolBarChirp = new System.Windows.Forms.ToolBar();
			this.toolBarLoad = new System.Windows.Forms.ToolBarButton();
			this.toolBarSave = new System.Windows.Forms.ToolBarButton();
			this.toolBarSep = new System.Windows.Forms.ToolBarButton();
			this.toolBarPlay = new System.Windows.Forms.ToolBarButton();
			this.toolBarParams = new System.Windows.Forms.ToolBarButton();
			this.toolBarSep2 = new System.Windows.Forms.ToolBarButton();
			this.toolBarLeft = new System.Windows.Forms.ToolBarButton();
			this.toolBarButton3 = new System.Windows.Forms.ToolBarButton();
			this.toolBarSep3 = new System.Windows.Forms.ToolBarButton();
			this.toolBarTestComplex = new System.Windows.Forms.ToolBarButton();
			this.imageChirp = new System.Windows.Forms.ImageList(this.components);
			this.sbChirp = new System.Windows.Forms.StatusBar();
			this.sbStatus = new System.Windows.Forms.StatusBarPanel();
			this.sbMic = new System.Windows.Forms.StatusBarPanel();
			this.sbPeak = new System.Windows.Forms.StatusBarPanel();
			this.sbRes = new System.Windows.Forms.StatusBarPanel();
			this.sbOut = new System.Windows.Forms.StatusBarPanel();
			this.sbIn = new System.Windows.Forms.StatusBarPanel();
			((System.ComponentModel.ISupportInitialize)(this.sbStatus)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.sbMic)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.sbPeak)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.sbRes)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.sbOut)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.sbIn)).BeginInit();
			this.SuspendLayout();
			// 
			// panel1
			// 
			this.panel1.Location = new System.Drawing.Point(24, 192);
			this.panel1.Name = "panel1";
			this.panel1.Size = new System.Drawing.Size(144, 72);
			this.panel1.TabIndex = 0;
			// 
			// panel2
			// 
			this.panel2.Location = new System.Drawing.Point(24, 288);
			this.panel2.Name = "panel2";
			this.panel2.Size = new System.Drawing.Size(144, 72);
			this.panel2.TabIndex = 1;
			// 
			// panel3
			// 
			this.panel3.Location = new System.Drawing.Point(24, 392);
			this.panel3.Name = "panel3";
			this.panel3.Size = new System.Drawing.Size(144, 72);
			this.panel3.TabIndex = 1;
			// 
			// lblTestLevel
			// 
			this.lblTestLevel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
			this.lblTestLevel.Location = new System.Drawing.Point(16, 512);
			this.lblTestLevel.Name = "lblTestLevel";
			this.lblTestLevel.TabIndex = 11;
			this.lblTestLevel.Text = "Test dB Level:";
			this.lblTestLevel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// txtTestLevel
			// 
			this.txtTestLevel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
			this.txtTestLevel.Location = new System.Drawing.Point(120, 512);
			this.txtTestLevel.Name = "txtTestLevel";
			this.txtTestLevel.Size = new System.Drawing.Size(64, 20);
			this.txtTestLevel.TabIndex = 12;
			this.txtTestLevel.Text = "60";
			// 
			// btnPlay
			// 
			this.btnPlay.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
			this.btnPlay.Image = ((System.Drawing.Image)(resources.GetObject("btnPlay.Image")));
			this.btnPlay.Location = new System.Drawing.Point(368, 511);
			this.btnPlay.Name = "btnPlay";
			this.btnPlay.Size = new System.Drawing.Size(32, 23);
			this.btnPlay.TabIndex = 13;
			this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click);
			// 
			// btnClosePlayer
			// 
			this.btnClosePlayer.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
			this.btnClosePlayer.Image = ((System.Drawing.Image)(resources.GetObject("btnClosePlayer.Image")));
			this.btnClosePlayer.Location = new System.Drawing.Point(440, 511);
			this.btnClosePlayer.Name = "btnClosePlayer";
			this.btnClosePlayer.Size = new System.Drawing.Size(32, 23);
			this.btnClosePlayer.TabIndex = 14;
			this.btnClosePlayer.Click += new System.EventHandler(this.btnClosePlayer_Click);
			// 
			// txtTestFreq
			// 
			this.txtTestFreq.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
			this.txtTestFreq.Location = new System.Drawing.Point(296, 512);
			this.txtTestFreq.Name = "txtTestFreq";
			this.txtTestFreq.Size = new System.Drawing.Size(64, 20);
			this.txtTestFreq.TabIndex = 16;
			this.txtTestFreq.Text = "1000";
			// 
			// lblTestFreq
			// 
			this.lblTestFreq.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
			this.lblTestFreq.Location = new System.Drawing.Point(192, 511);
			this.lblTestFreq.Name = "lblTestFreq";
			this.lblTestFreq.TabIndex = 15;
			this.lblTestFreq.Text = "Test Frequency:";
			this.lblTestFreq.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// lblCurSeg
			// 
			this.lblCurSeg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this.lblCurSeg.Location = new System.Drawing.Point(672, 502);
			this.lblCurSeg.Name = "lblCurSeg";
			this.lblCurSeg.Size = new System.Drawing.Size(56, 24);
			this.lblCurSeg.TabIndex = 44;
			this.lblCurSeg.Text = "Cur Seg:";
			this.lblCurSeg.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// tbCurSeg
			// 
			this.tbCurSeg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this.tbCurSeg.Location = new System.Drawing.Point(736, 504);
			this.tbCurSeg.Name = "tbCurSeg";
			this.tbCurSeg.Size = new System.Drawing.Size(48, 20);
			this.tbCurSeg.TabIndex = 43;
			this.tbCurSeg.Text = "-1";
			// 
			// toolBarChirp
			// 
			this.toolBarChirp.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
																							this.toolBarLoad,
																							this.toolBarSave,
																							this.toolBarSep,
																							this.toolBarPlay,
																							this.toolBarParams,
																							this.toolBarSep2,
																							this.toolBarLeft,
																							this.toolBarButton3,
																							this.toolBarSep3,
																							this.toolBarTestComplex});
			this.toolBarChirp.DropDownArrows = true;
			this.toolBarChirp.ImageList = this.imageChirp;
			this.toolBarChirp.Location = new System.Drawing.Point(0, 0);
			this.toolBarChirp.Name = "toolBarChirp";
			this.toolBarChirp.ShowToolTips = true;
			this.toolBarChirp.Size = new System.Drawing.Size(792, 28);
			this.toolBarChirp.TabIndex = 45;
			this.toolBarChirp.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBarChirp_ButtonClick);
			// 
			// toolBarLoad
			// 
			this.toolBarLoad.ImageIndex = 1;
			this.toolBarLoad.ToolTipText = "Load";
			// 
			// toolBarSave
			// 
			this.toolBarSave.ImageIndex = 2;
			this.toolBarSave.ToolTipText = "Save";
			// 
			// toolBarSep
			// 
			this.toolBarSep.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
			// 
			// toolBarPlay
			// 
			this.toolBarPlay.ImageIndex = 3;
			this.toolBarPlay.ToolTipText = "Play/Record Chirp";
			// 
			// toolBarParams
			// 
			this.toolBarParams.ImageIndex = 4;
			this.toolBarParams.ToolTipText = "Parameters";
			// 
			// toolBarSep2
			// 
			this.toolBarSep2.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
			// 
			// toolBarLeft
			// 
			this.toolBarLeft.ImageIndex = 5;
			this.toolBarLeft.ToolTipText = "Set as Left Channel Calibration";
			this.toolBarLeft.Visible = false;
			// 
			// toolBarButton3
			// 
			this.toolBarButton3.ImageIndex = 6;
			this.toolBarButton3.ToolTipText = "Set as Right Channel Calibration";
			this.toolBarButton3.Visible = false;
			// 
			// toolBarSep3
			// 
			this.toolBarSep3.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
			// 
			// toolBarTestComplex
			// 
			this.toolBarTestComplex.ImageIndex = 7;
			this.toolBarTestComplex.ToolTipText = "Write Complex Stims (from .def file)";
			// 
			// imageChirp
			// 
			this.imageChirp.ImageSize = new System.Drawing.Size(16, 16);
			this.imageChirp.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageChirp.ImageStream")));
			this.imageChirp.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// sbChirp
			// 
			this.sbChirp.Location = new System.Drawing.Point(0, 544);
			this.sbChirp.Name = "sbChirp";
			this.sbChirp.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
																					   this.sbStatus,
																					   this.sbMic,
																					   this.sbPeak,
																					   this.sbRes,
																					   this.sbOut,
																					   this.sbIn});
			this.sbChirp.ShowPanels = true;
			this.sbChirp.Size = new System.Drawing.Size(792, 22);
			this.sbChirp.TabIndex = 46;
			this.sbChirp.Text = "statusBar1";
			// 
			// sbStatus
			// 
			this.sbStatus.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
			this.sbStatus.BorderStyle = System.Windows.Forms.StatusBarPanelBorderStyle.Raised;
			this.sbStatus.Text = "Status";
			this.sbStatus.Width = 129;
			// 
			// sbMic
			// 
			this.sbMic.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
			this.sbMic.Text = "Mic:";
			this.sbMic.Width = 129;
			// 
			// sbPeak
			// 
			this.sbPeak.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
			this.sbPeak.Text = "Peak:";
			this.sbPeak.Width = 129;
			// 
			// sbRes
			// 
			this.sbRes.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
			this.sbRes.Text = "Res:";
			this.sbRes.Width = 129;
			// 
			// sbOut
			// 
			this.sbOut.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
			this.sbOut.Text = "Max Out:";
			this.sbOut.Width = 129;
			// 
			// sbIn
			// 
			this.sbIn.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
			this.sbIn.Text = "Max In:";
			this.sbIn.Width = 129;
			// 
			// Chirp
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(792, 566);
			this.Controls.Add(this.sbChirp);
			this.Controls.Add(this.toolBarChirp);
			this.Controls.Add(this.lblCurSeg);
			this.Controls.Add(this.tbCurSeg);
			this.Controls.Add(this.txtTestFreq);
			this.Controls.Add(this.txtTestLevel);
			this.Controls.Add(this.lblTestFreq);
			this.Controls.Add(this.btnClosePlayer);
			this.Controls.Add(this.btnPlay);
			this.Controls.Add(this.lblTestLevel);
			this.Controls.Add(this.panel1);
			this.Controls.Add(this.panel2);
			this.Controls.Add(this.panel3);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Name = "Chirp";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "Chirp";
			this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
			
			((System.ComponentModel.ISupportInitialize)(this.sbStatus)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.sbMic)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.sbPeak)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.sbRes)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.sbOut)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.sbIn)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion
		public void Init()
		{
			// When the recording is done it fires off this event
			//rec.ReadDone += new EventHandler(rec_ReadDone);

			int x = this.Width;
			int y = this.Height;
			int BottomSpace = this.Height - txtTestLevel.Location.Y;
			int ySize = (y-BottomSpace-50)/3;

			panel1.Size = new Size(x-50,ySize);
			panel2.Size = new Size(x-50,ySize);
			panel3.Size = new Size(x-50,ySize);
			panel1.Location = new Point(8,30);
			panel2.Location = new Point(8,40+ySize);
			panel3.Location = new Point(8,50+2*(ySize));
			graph1.SetPanel(panel1);
			graph2.SetPanel(panel2);
			graph3.SetPanel(panel3);
			graph1.SetSize(panel1.Size);
			graph2.SetSize(panel2.Size);
			graph3.SetSize(panel3.Size);
			graph1.title = "Source";
			graph2.title = "Response";
			graph3.title = "20 log (Response/Source)";
			graph1.xlabel = "Frequency (Hz)";
			graph2.xlabel = "Frequency (Hz)";
			graph3.xlabel = "Frequency (Hz)";
			graph1.ylabel = "";
			graph2.ylabel = "";
			graph3.ylabel = "dB";
			graph2.ForeColor = Color.Yellow;
			graph3.ForeColor = Color.CornflowerBlue;
			graph2.AddLine(Color.Blue);
			graph2.AddLine(Color.Red);
			graph3.AddLine(Color.Blue);
			graph3.AddLine(Color.Red);
			try
			{
				if(mainmenu.LeftCal!=null)
				{
					for(int z=0;z<mainmenu.LeftCal.Response.Count;z++)
					{
						if(z%8==0)
							graph2.AddPoint(0,(double)mainmenu.LeftCal.Response[z]);
					}
					for(int z=0;z<mainmenu.LeftCal.Cal.Count;z++)
					{
						if(z%8==0)
							graph3.AddPoint(0,(double)mainmenu.LeftCal.Cal[z]);
					}
				}
				if(mainmenu.RightCal!=null)
				{
					for(int z=0;z<mainmenu.RightCal.Response.Count;z++)
					{
						if(z%8==0)
							graph2.AddPoint(1,(double)mainmenu.RightCal.Response[z]);
					}
					for(int z=0;z<mainmenu.RightCal.Cal.Count;z++)
					{
						if(z%8==0)
							graph3.AddPoint(1,(double)mainmenu.RightCal.Cal[z]);
					}
				}
				Draw();
			}
			catch(Exception err)
			{
				Form1.ErrorMsg(err.Message);
			}
						
		}
		public void Draw()
		{
			graph1.Draw(PointToScreen(panel1.Location));
			graph2.Draw(PointToScreen(panel2.Location));
			graph3.Draw(PointToScreen(panel3.Location));
		}
		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint (e);
			Draw();
		}
		private void ShowStats()
		{
			sbMic.Text = "Mic: " + cprms.Mic.Text+" uV = 0dB SPL";
			sbPeak.Text = "Peak: " + cprms.Level.Text + " V";
			sbRes.Text = "Resolution: " + cprms.MaxInt.Text+" bits";
			this.sbOut.Text = "Max Out: " + cprms.MaxOut.Text + " V";
			sbIn.Text = "Max In: " + cprms.MaxIn.Text + " V";
		}
		private void ShowTest()
		{
			lblTestFreq.Visible = true;
			lblTestLevel.Visible = true;
			txtTestFreq.Visible = true;
			txtTestLevel.Visible = true;
			btnPlay.Visible = true;
			btnClosePlayer.Visible = true;
		}
		private void toolBarChirp_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
		{
			EventArgs ev = new EventArgs();
			switch(toolBarChirp.Buttons.IndexOf(e.Button))
			{
				case 0:
					btnLoadCal_Click(sender, ev);
					break;
				case 1:
					btnSaveCal_Click(sender, ev);
					break;
				case 3:
					PlayChirp();
					break;
				case 4:
					SetParams();
					break;
				case 6:
					SetLeft();
					break;
				case 7:
					SetRight();
					break;
				case 9:
					WriteComplexStims();
					break;

			}
		}
		private void btnSaveCal_Click(object sender, System.EventArgs e)
		{
			try
			{
				SaveFileDialog dlg = new SaveFileDialog();
				dlg.Filter = "Calibration file (*.cal)|*.cal";
				dlg.Filter += "|All files|*.*";
				dlg.OverwritePrompt = true;
				if(dlg.ShowDialog()==DialogResult.OK)
				{
					StreamWriter s = new StreamWriter(dlg.FileName,false);
					s.WriteLine(cprms.Level.Text);
					s.WriteLine(cprms.Mic.Text);
					s.WriteLine(cprms.MaxInt.Text);
					s.WriteLine(cprms.MaxOut.Text);
					s.WriteLine(cprms.MaxIn.Text);
					s.WriteLine("LEFT RESPONSE");
					for(int y=0;y<mainmenu.LeftCal.Response.Count;y++)
					{
						double x = (double) mainmenu.LeftCal.Response[y];
						s.WriteLine(x.ToString("#####.0000"));
					}
					s.WriteLine("LEFT CHANNEL");
					for(int y=0;y<mainmenu.LeftCal.Cal.Count;y++)
					{
						double x = (double) mainmenu.LeftCal.Cal[y];
						s.WriteLine(x.ToString("#####.0000"));
					}
					s.WriteLine("RIGHT RESPONSE");
					for(int y=0;y<mainmenu.RightCal.Response.Count;y++)
					{
						double x = (double) mainmenu.RightCal.Response[y];
						s.WriteLine(x.ToString("#####.0000"));
					}
					s.WriteLine("RIGHT CHANNEL");
					for(int y=0;y<mainmenu.RightCal.Cal.Count;y++)
					{
						double x = (double) mainmenu.RightCal.Cal[y];
						s.WriteLine(x.ToString("#####.0000"));
					}
					s.Flush();
					s.Close();
				}
			}
			catch (IOException ex)
			{	
				MessageBox.Show(ex.Message);
			}
		}

		private void btnLoadCal_Click(object sender, System.EventArgs e)
		{
			try
			{
				OpenFileDialog dlg = new OpenFileDialog();
				dlg.Filter = "Calibration file (*.cal)|*.cal";
				dlg.Filter += "|All files|*.*";
				dlg.Multiselect = false;
				if(dlg.ShowDialog()==DialogResult.OK)
				{
					StreamReader s = new StreamReader(dlg.FileName);
					graph1.ClearPtList();
					graph2.ClearPtList();
					graph3.ClearPtList();
					graph2.AddLine(Color.Blue);
					graph2.AddLine(Color.Red);
					graph3.AddLine(Color.Blue);
					graph3.AddLine(Color.Red);

					//load params
					cprms.Level.Text = s.ReadLine();
					cprms.Mic.Text = s.ReadLine();
					cprms.MaxInt.Text = s.ReadLine();
					cprms.MaxOut.Text = s.ReadLine();
					cprms.MaxIn.Text = s.ReadLine();

					//set params
					dLevel = double.Parse(cprms.Level.Text);
					nMic = int.Parse(cprms.Mic.Text);
					nMaxInt = int.Parse(cprms.MaxInt.Text);
					dMaxOut = double.Parse(cprms.MaxOut.Text);
					dMaxIn = double.Parse(cprms.MaxIn.Text);
					double dsingle = dMaxOut/(Math.Pow(2,nMaxInt-1)-1);
					int nLevel = (int) (dLevel/dsingle);
					//init structures
					left = new ChirpCal();
					left.Cal = new ArrayList();
					left.dMaxIn = this.dMaxIn;
					left.dMaxOut = this.dMaxOut;
					left.dLevel = (dLevel/dsingle);
					left.nMaxInt = (int) Math.Pow(2,this.nMaxInt-1)-1;
					left.nMic = this.nMic;
					left.Init();
					left.strFile = dlg.FileName;
					right = new ChirpCal();
					right.Cal = new ArrayList();
					right.dMaxIn = this.dMaxIn;
					right.dMaxOut = this.dMaxOut;
					right.dLevel = (dLevel/dsingle);
					right.nMaxInt = (int) Math.Pow(2,this.nMaxInt-1)-1;
					right.nMic = this.nMic;
					right.Init();
					right.strFile = dlg.FileName;
					//read datapoints
					string strLine = s.ReadLine();//should be LEFT CHANNEL
					if(strLine!="LEFT RESPONSE")
					{
						Form1.ErrorMsg("Invalid cal file!  (Old style perhaps?)");
						return;
					}
					strLine = s.ReadLine();//first number
					int cnt = 0;
					while(strLine!="LEFT CHANNEL")
					{
						double d = double.Parse(strLine);
						if(cnt++%8==0)
							graph2.AddPoint(0,d);
						left.Response.Add(d);
						strLine = s.ReadLine();
					}
					strLine = s.ReadLine();//first number
					while(strLine!="RIGHT RESPONSE")
					{
						double d = double.Parse(strLine);
						if(cnt++%8==0)
							graph3.AddPoint(0,d);
						left.Cal.Add(d);
						strLine = s.ReadLine();
					}
					strLine = s.ReadLine();//first number
					while(strLine!="RIGHT CHANNEL")
					{
						double d = double.Parse(strLine);
						if(cnt++%8==0)
							graph2.AddPoint(1,d);
						right.Response.Add(d);
						strLine = s.ReadLine();
					}
					strLine = s.ReadLine();//first number
					while(strLine!=null)
					{
						double d = double.Parse(strLine);
						if(cnt++%8==0)
							graph3.AddPoint(1,d);
						right.Cal.Add(d);
						strLine = s.ReadLine();
					}
					//set cal
					mainmenu.LeftCal = left;
					mainmenu.RightCal = right;

					mainmenu.SetLeftCalibration("Chirp Calibration: "+dlg.FileName);
					mainmenu.SetRightCalibration("Chirp Calibration: "+dlg.FileName);
					s.Close();
					Draw();
					this.Update();
					ShowTest();
				}
			}
			catch(IOException ex)
			{
				MessageBox.Show(ex.Message);
			}

		}
		
	
		private void PlayChirp()
		{
			CalList.Clear();
			// WaveRecorder initialization
			rec.ifrmParentForm = this;
			rec.SetSampleRate(nSam);
			if ( ! rec.Init() ) return;		

			dLevel = double.Parse(cprms.Level.Text);
			nMic = int.Parse(cprms.Mic.Text);
			nMaxInt = int.Parse(cprms.MaxInt.Text);
			dMaxOut = double.Parse(cprms.MaxOut.Text);
			dMaxIn = double.Parse(cprms.MaxIn.Text);
			double dsingle = dMaxOut/(Math.Pow(2,nMaxInt-1)-1);
			int nLevel = (int) (dLevel/dsingle);

			// This creates the chirp data
			chirp.Chirp(nLevel,16384,1,WaveBuffer.Ears.Both,false,nSam);//earlier end-freq 16384
			// Writes to c:\
			FileInfo f = new FileInfo( @"c:\chirp.wav" );
			//write the source
			chirp.WriteWave(f);
			b2 = Average(chirp,true);
			//write the average
			f = new FileInfo(@"c:\cal.wav");
			b2.WriteWave(f);

			//left ear
			chirp.Chirp(nLevel,16384,1,WaveBuffer.Ears.Left,false,nSam);//earlier end-freq 16384
			// Set our record output buffer to play chirp
			chirp.ms.Seek(0, SeekOrigin.Begin);
			rec.iwbOutBuff = chirp;

			// Open the soundcard for recording
			try{if ( ! rec.Open() ) return;}
			catch(Exception err)
			{
				MessageBox.Show(err.Message);
				return;
			}
			if ( ! rec.Record() ) return;
			WaveBuffer wbLeft = rec.iwbInBuff;
//Right ear
			chirp.Chirp(nLevel,16384,1,WaveBuffer.Ears.Right,false,nSam); //16384
			rec.Clear();
			// Set our record output buffer to play chirp
			chirp.ms.Seek(0, SeekOrigin.Begin);
			rec.iwbOutBuff = chirp;

			if ( ! rec.Record() ) return;
			WaveBuffer wbRight = rec.iwbInBuff;
			mainmenu.MaxAmplitude = 8388607;
			sbStatus.Text = "PLAYING";
			this.Update();
			// Manually call the function that used to be handled by an event.
			rec_ReadDone (wbLeft, wbRight);
		}
		private unsafe void rec_ReadDone(WaveBuffer wbLeft, WaveBuffer wbRight)
		{
			try
			{
				sbStatus.Text = "ANALYZING";
				this.Update();
				graph1.ClearPtList();
				graph2.ClearPtList();
				graph3.ClearPtList();
				graph1.AddLine(Color.White);
				graph2.AddLine(Color.Blue);
				graph2.AddLine(Color.Red);
				graph3.AddLine(Color.Blue);
				graph3.AddLine(Color.Red);
				//graph1.bFFT = true;
				//graph2.bFFT = true;
				//graph3.bFFT = true;
				
				this.Update();

				//display source
				float[] source = b2.ToFloatArray();
				fixed(float* ptr = &source[0])
				{
					if(SigPro.sp_rcfft(ptr,source.Length)!=0)
						return;
				}
				int zz =source.Length;
				double dist;
				double[] so = new double[zz/2];
				int socnt = 0;
				for(int j=0;j<zz;j++)
				{
					dist = source[j]*source[j]+source[j+1]*source[j+1];
					so[socnt] = (double)Math.Sqrt(dist);
					if(j%16==0)
						graph1.AddPoint(0,so[socnt]);
					socnt++;
					j++;//don't graph the complex part
				}

				//Average.
				wbLeft.ms.Seek((int)(this.nSam/1000*1.5*4),SeekOrigin.Begin);
				WaveBuffer newbuff = Average(wbLeft,true);
				float[] result = newbuff.ToFloatArray();
				fixed(float* ptr = &result[0])
				{
					if(SigPro.sp_rcfft(ptr,result.Length)!=0)
						return;
				}
				zz = result.Length;
				double[] res = new double[zz/2];
				int rescnt = 0;
				left = new ChirpCal();
				for(int j=0;j<zz;j++)
				{
					dist = result[j]*result[j]+result[j+1]*result[j+1];
					res[rescnt]=(double)Math.Sqrt(dist);
					if(j%16==0)
						graph2.AddPoint(0,res[rescnt]);
					left.Response.Add(res[rescnt]);
					rescnt++;
					j++;//don't graph the complex part
				}
				double dd;
				double yy;
				zz = res.Length;
				if(so.Length<zz)
					zz = so.Length;

				for(int j=0;j<zz;j++)
				{
					dd = (res[j]*2)/so[j];//*2 because input is 10v, output is 5v
					yy = 20* Math.Log10(Math.Abs(dd));
					if(j%8==0)
						graph3.AddPoint(0,yy);
					left.Cal.Add(yy);
				}
				left.dMaxIn = this.dMaxIn;
				left.dMaxOut = this.dMaxOut;
				double dsingle = dMaxOut/Math.Pow(2,nMaxInt-1);
				left.dLevel = (dLevel/dsingle);
				left.nMaxInt = (int) Math.Pow(2,this.nMaxInt-1)-1;
				left.nMic = this.nMic;
				left.Init();
				mainmenu.LeftCal = this.left;
				WriteCalValues(left,"Cal.txt","LEFT CHANNEL", false);
				//Right
				wbRight.ms.Seek((int)(this.nSam/1000*1.5*4),SeekOrigin.Begin);
				newbuff = Average(wbRight,true);
				result = newbuff.ToFloatArray();
				fixed(float* ptr = &result[0])
				{
					if(SigPro.sp_rcfft(ptr,result.Length)!=0)
						return;
				}
				zz = result.Length;
				res = new double[zz/2];
				rescnt = 0;
				right = new ChirpCal();
				for(int j=0;j<zz;j++)
				{
					dist = result[j]*result[j]+result[j+1]*result[j+1];
					res[rescnt]=(double)Math.Sqrt(dist);
					if(j%16==0)
						graph2.AddPoint(1,res[rescnt]);
					right.Response.Add(res[rescnt]);
					rescnt++;
					j++;//don't graph the complex part
				}
				zz = res.Length;
				if(so.Length<zz)
					zz = so.Length;

				for(int j=0;j<zz;j++)
				{
					dd = (res[j]*2)/so[j];//*2 because input is 10v, output is 5v
					yy = 20* Math.Log10(Math.Abs(dd));
					if(j%8==0)
						graph3.AddPoint(1,yy);
					right.Cal.Add(yy);
				}
				//bReady = true;
				sbStatus.Text = "DONE";
				Draw();
				rec.Close();
				
				right.dMaxIn = this.dMaxIn;
				right.dMaxOut = this.dMaxOut;
				dsingle = dMaxOut/Math.Pow(2,nMaxInt-1);
				right.dLevel = (dLevel/dsingle);
				right.nMaxInt = (int) Math.Pow(2,this.nMaxInt-1)-1;
				right.nMic = this.nMic;
				right.Init();
				WriteCalValues(right,"Cal.txt","RIGHT CHANNEL", true);
				mainmenu.RightCal = this.right;
				mainmenu.SetLeftCalibration("Chirp Calibration Performed");
				mainmenu.SetRightCalibration("Chirp Calibration Performed");
				ShowTest();
			}
			catch(Exception err)
			{
				MessageBox.Show(err.Message);
				return;
			}
		}

		private void SetParams()
		{
			cprms.ShowDialog();
			ShowStats();
			this.Update();
			this.Draw();
		}
		private void SetLeft()
		{
			mainmenu.LeftCal = this.cal;
			mainmenu.SetLeftCalibration(cal.strFile);
			//mainmenu.LeftCal.Init();
		}
		private void SetRight()
		{
			mainmenu.RightCal = this.cal;
			mainmenu.SetRightCalibration(cal.strFile);
			//mainmenu.RightCal.Init();
		}
		private WaveBuffer Average(WaveBuffer i,bool bLeft)
		{
			int abc = 8192;
			MemoryStream[] ms = new MemoryStream[8];
			for(int n=1;n<8;n++)
			{
				ms[n] = new MemoryStream(abc*4*2);
				byte[] bb = new byte[abc*4*2];
				i.ms.Read(bb,0,abc*4*2);
				ms[n].Write(bb,0,abc*4*2);
			}
			MemoryStream mem = new MemoryStream(abc*4*2);
			BinaryReader[] r = new BinaryReader[8];
			for(int n=1;n<8;n++)
			{
				r[n] = new BinaryReader(ms[n]);
				ms[n].Seek(0,SeekOrigin.Begin);
			}
			BinaryWriter w = new BinaryWriter(mem);
			for(int n=0;n<abc;n++)
			{
				int suml = 0;
				int sumr = 0;
				for(int x=1;x<8;x++)
				{
					if(bLeft)
					{
						suml+=r[x].ReadInt32()>>8;
						sumr=r[x].ReadInt32()>>8;
					}
					else
					{
						suml+=r[x].ReadInt32();
						sumr=r[x].ReadInt32();
					}
				}
				w.Write((int)(suml/8));
				w.Write((int)(sumr/8));
			}
			WaveBuffer newbuff =  new WaveBuffer();
			newbuff.SampleRate = nSam;
			newbuff.ManualBuffer(ref mem);
			return newbuff;
		}
		
	/*	public EngMATLib.Matrix GetMatrix(WaveBuffer buf,bool bLeft)
		{
			buf.ms.Seek(0,SeekOrigin.Begin);
			int x = 0;
			double[] d = new double[(int)(buf.ms.Length/4)/2];
			for(int i = 0;i<(buf.ms.Length/4)/2;i++)
			{
				x = buf.reader.ReadInt32();
				if(bLeft==true)
					d[i] = x>>8;
				else
					d[i] = x;
				x = buf.reader.ReadInt32();
			}
			Matrix m = new Matrix(d,1);
			return m;

		}
*/
		private void Play_Click(object sender, System.EventArgs e)
		{
			ARSC.ARSCWrite("Start Play");
			CalList.Clear();

			// WaveRecorder initialization
			rec.ifrmParentForm = this;
			rec.SetSampleRate(nSam);
			if ( ! rec.Init() ) return;

			dLevel = double.Parse(cprms.Level.Text);
			nMic = int.Parse(cprms.Text);
			nMaxInt = int.Parse(cprms.MaxInt.Text);
			dMaxOut = double.Parse(cprms.MaxOut.Text);
			dMaxIn = double.Parse(cprms.MaxIn.Text);
			double dsingle = dMaxOut/(Math.Pow(2,nMaxInt-1)-1);
			int nLevel = (int) (dLevel/dsingle);

			// This creates the chirp data
			chirp.Chirp(nLevel,16384,1,WaveBuffer.Ears.Both,false,nSam);

			// Writes to c:\
			FileInfo f = new FileInfo( @"c:\chirp.wav" );
			//take out a<<8 in WaveBuffer.Chirp to write to file
			chirp.WriteWave(f);

			b2 = Average(chirp,true);

			// Writes to c:\
			f = new FileInfo(@"c:\cal.wav");
			b2.WriteWave(f);

			// Set our record output buffer to play chirp
			chirp.ms.Seek(0, SeekOrigin.Begin);
			rec.iwbOutBuff = chirp;

			ARSC.ARSCWrite("Open Soundcard");
			// Open the soundcard for recording
			if ( ! rec.Open() ) return;

			mainmenu.MaxAmplitude = 8388607;
			sbStatus.Text = "PLAYING";
			this.Update();

			ARSC.ARSCWrite("Start Recording");
			// Start recording.  An event is called when we are done.
			if ( ! rec.Record() ) return;
			ARSC.ARSCWrite("Done Recording");

			// Manually call the function that used to be handled by an event.
		//	rec_ReadDone ( rec.iwbInBuff.ToFloatArray(), null );

		}

		// This was the event handled called when the recording was done.
		private void WriteCalValues(ChirpCal cal, string FileName, string strTitle, bool bAppend)
		{
			//(int) (Freq/4);
			StreamWriter s = new StreamWriter(FileName,bAppend);
			s.WriteLine(strTitle);
			WriteKey(s);
			WriteCal(s,cal,200);
			WriteCal(s,cal,250);
			WriteCal(s,cal,315);
			WriteCal(s,cal,400);
			WriteCal(s,cal,500);
			WriteCal(s,cal,630);
			WriteCal(s,cal,800);
			WriteCal(s,cal,1000);
			WriteCal(s,cal,1250);
			WriteCal(s,cal,1600);
			WriteCal(s,cal,2000);
			WriteCal(s,cal,2500);
			WriteCal(s,cal,3150);
			WriteCal(s,cal,4000);
			WriteCal(s,cal,5000);
			WriteCal(s,cal,6300);
			WriteCal(s,cal,8000);
			WriteCal(s,cal,9000);
			WriteCal(s,cal,10000);
			s.Flush();
			s.Close();
		}
		private void WriteKey(StreamWriter s)
		{
			s.WriteLine("Values listed (in order):");
			s.WriteLine("200");
			s.WriteLine("250");
			s.WriteLine("315");
			s.WriteLine("400");
			s.WriteLine("500");
			s.WriteLine("630");
			s.WriteLine("800");
			s.WriteLine("1000");
			s.WriteLine("1250");
			s.WriteLine("1600");
			s.WriteLine("2000");
			s.WriteLine("2500");
			s.WriteLine("3150");
			s.WriteLine("4000");
			s.WriteLine("5000");
			s.WriteLine("6300");
			s.WriteLine("8000");
			s.WriteLine("9000");
			s.WriteLine("10000");

		}
		private void WriteCal(StreamWriter s, ChirpCal cal, int Freq)
		{
			//int y = (int) Freq/4;
			int y = (int) Freq;
			double x = (double) cal.Cal[y];
			s.WriteLine(x.ToString("#####.00"));
		}
		private void btnPlay_Click(object sender, System.EventArgs e)
		{
			player.ifrmParentForm = this;
			player.Init();
			if(player.Open()==false)
			{
				MessageBox.Show("Unable to open sound card!","Audio Error",MessageBoxButtons.OK,MessageBoxIcon.Stop);
				return;
			}
			int MaxAmplitude = (int) Math.Pow(2,this.nMaxInt-1)-1;
			int TestLevel = int.Parse(txtTestLevel.Text);
			int Freq = int.Parse(txtTestFreq.Text);
			//double V2 = this.cal.CalcInt(TestLevel,Freq);
			double V2 = mainmenu.GetV2(TestLevel,Freq,"both");
			if ( V2 == -1 )	{
				MessageBox.Show("Run START button first.");
				return;
			}
			if(player.Signals[0]!=null)
			{
				player.Signals[0].Stop();
				player.Signals[0].Dispose();
			}

			player.Signals[0] = new WaveBuffer();
			player.Signals[0].AmplificationType = AmplificationTypes.Peak;
			player.Signals[0].Tone(MaxAmplitude,Freq,0,4000,20,20,WaveBuffer.Ears.Both,true);
			//player.Signals[0].Pulse(MaxAmplitude,nFreq,300,20,20,100,WaveBuffer.Ears.Both,true);
			player.Signals[0].SetLevel((int) V2);
			player.Signals[0].Play();
			sbStatus.Text = "Test Tone";
			sbChirp.Update();
			
			//player.bStreaming = false;
			player.PlaySingleSignal();
			//player.Signals[0].Play();
			//player.Play();

			sbStatus.Text = "Done";
			sbChirp.Update();
			player.Close();
		}

		private void btnClosePlayer_Click(object sender, System.EventArgs e)
		{
			if ( rec != null ) rec.Stop();
			if ( player != null ) player.Stop();
		}

		private void Chirp_Closing(object sender, CancelEventArgs e)
		{
			try
			{
				rec.Close();
				player.Close();
				player.Dispose();
				rec.Dispose();
			}
			catch(Exception)
			{
				//MessageBox.Show(err.Message);
			}
		}

		private void WriteComplexStims()
		{
			if(mainmenu.ReadInitFile(null)==false)
			{
				MessageBox.Show("Unable to read .def file (from main screen)");
				return;
			}
			int n=1;
			foreach(Stim s in mainmenu.def.PrimaryStims)
			{
				if(s is ComplexStim)
				{
					ComplexStim cs = (ComplexStim) s;
					for(int j=0;j<cs.nNumberOfStims;j++)
					{
						Stim sub = (Stim) cs.listStims[j];
						mainmenu.CreateStim(ref sub);
						int nLevel = mainmenu.GetV2(sub.nOrigin,sub.nFreq,sub.strEar);
						sub.buffer.SetLevel(nLevel);
					}
					cs.Mix();
					FileInfo file = new FileInfo(@"C:\Primary"+n.ToString()+".wav");
					cs.buffer.WriteStereoWave(file);
				}
			}
			foreach(Stim s in mainmenu.def.SecondaryStims)
			{
				if(s is ComplexStim)
				{
					ComplexStim cs = (ComplexStim) s;
					for(int j=0;j<cs.nNumberOfStims;j++)
					{
						Stim sub = (Stim) cs.listStims[j];
						mainmenu.CreateStim(ref sub);
						int nLevel = mainmenu.GetV2(sub.nOrigin,sub.nFreq,sub.strEar);
						sub.buffer.SetLevel(nLevel);
					}
					cs.Mix();
					FileInfo file = new FileInfo(@"C:\Secondary"+n.ToString()+".wav");
					cs.buffer.WriteStereoWave(file);
				}
			}

		}

		
	}
}
