예제 #1
0
파일: Sound.cs 프로젝트: Earlvik/ArtiStereo
 public Sound(Sound other)
 {
     mChannels = other.mChannels;
     mDescretionRate = other.mDescretionRate;
     mBitsPerSample = other.mBitsPerSample;
     mSound = new float[mChannels][];
     for (int i = 0; i < mChannels; i++)
     {
         mSound[i]=new float[other.mSound[i].Length];
         Array.Copy(other.mSound[i],mSound[i],other.mSound[i].Length);
     }
 }
예제 #2
0
파일: Sound.cs 프로젝트: Earlvik/ArtiStereo
 /// <summary>
 /// Combination of sound copying and volume adjusting
 /// </summary>
 /// <param name="percent">Target volume level in percents</param>
 /// <param name="channel">Channel to use in setVolume</param>
 /// <returns></returns>
 public Sound CopyWithVolume( double percent, int channel)
 {
     Sound result = new Sound(this);
     result.SetVolume(percent,channel);
     return result;
 }
예제 #3
0
파일: Sound.cs 프로젝트: Earlvik/ArtiStereo
 bool SameSized(Sound sound)
 {
     if (mSound == null || sound.mSound == null) return false;
     if (mSound.Length != sound.mSound.Length) return false;
     for (int i = 0; i < mSound.Length; i++)
     {
         if (mSound[i].Length != sound.mSound[i].Length) return false;
     }
     return true;
 }
예제 #4
0
파일: Sound.cs 프로젝트: Earlvik/ArtiStereo
 public void Convolve(Sound kernel,int channelTo, int channelFrom)
 {
     FloatVector kernelVector = new FloatVector(kernel.mSound[channelFrom]);
     FloatVector dataVector = new FloatVector(mSound[channelTo]);
     Float1DConvolution convolution = new Float1DConvolution(kernelVector,dataVector.Length);
     FloatVector result = convolution.Convolve(dataVector);
     mSound[channelTo] = result.ToArray();
 }
예제 #5
0
파일: Sound.cs 프로젝트: Earlvik/ArtiStereo
 public void Copy(Sound sound)
 {
     mChannels = sound.mChannels;
     mDescretionRate = sound.mDescretionRate;
     mBitsPerSample = sound.mBitsPerSample;
     if (!SameSized(sound))
     {
         mSound = new float[mChannels][];
         for (int i = 0; i < mChannels; i++)
         {
             mSound[i] = new float[sound.mSound[i].Length];
             Array.Copy(sound.mSound[i], mSound[i], sound.mSound[i].Length);
         }
     }
     else
     {
         for (int i = 0; i < mChannels; i++)
         {
             Array.Copy(sound.mSound[i], mSound[i], sound.mSound[i].Length);
         }
     }
 }
예제 #6
0
파일: Sound.cs 프로젝트: Earlvik/ArtiStereo
        /// <summary>
        /// Create simple sine soundwave
        /// </summary>
        /// <param name="freq">Frequency of wave</param>
        /// <returns></returns>
        public static Sound SimpleWave(int freq)
        {
            Sound result = new Sound(1, 44100, 16);
            result.mSound = new float[1][];
            result.mSound[0] = new float[result.mDescretionRate*10];
            for (int i = 0; i < result.mSound[0].Length; i++)
            {
                double x = freq*i/(result.mDescretionRate*Math.PI);
                result.mSound[0][i] = (float) Math.Sin(x);

            }
            return result;
        }
예제 #7
0
파일: Sound.cs 프로젝트: Earlvik/ArtiStereo
        /// <summary>
        /// Adding one sound to another
        /// </summary>
        /// <param name="sound">Sound to add</param>
        /// <param name="channelFrom">Channel of sound to use for sum</param>
        /// <param name="channelTo">Target channel of sound</param>
        /// <param name="offset">Time offset in milliseconds</param>
        /// <param name="volume">Optional parameter to add with certain volume level</param>
        public void Add(Sound sound,int channelFrom,int channelTo, int offset, double volume = 1)
        {
            if(channelTo>mChannels || channelTo<0) throw new ArgumentException("Channel number invalid");
            if (channelFrom > sound.mChannels || channelFrom<0) throw new ArgumentException("Channel number invalid");
            if(mDescretionRate != sound.mDescretionRate) throw new ArgumentException("different discretion rates");

            if(mSound[channelTo] == null) mSound[channelTo] = new float[0];
            float[] fromSound = sound.mSound[channelFrom];
            float[] temp = new float[Math.Max(mSound[channelTo].Length, offset + fromSound.Length)];
            for (int i = 0; i < mSound[channelTo].Length; i++)
            {
                temp[i] = mSound[channelTo][i];
            }
            mSound[channelTo] = null;
            for (int i = offset; i < temp.Length; i++)
            {
                temp[i] += i - offset < fromSound.Length ? (float)volume*fromSound[i - offset] : 0;

            }
            mSound[channelTo] = temp;
        }
예제 #8
0
        private void RecordButton_Click(object sender, RoutedEventArgs e)
        {
            if (!mRoom.IsValid())
            {
                MessageBox.Show(this, "Room is invalid, check status bar for further instructions");
                return;
            }
            try
            {
                mReflectionWorker = new BackgroundWorker();
                mReflectionWorker.WorkerSupportsCancellation = true;
                RecordButton.IsEnabled = false;
                for (int i = 0; i < buttonNumber - 1; i++)
                {
                    mToolButtons[i].IsChecked = false;
                    mToolButtons[i].IsEnabled = false;
                }
                RoomOpenMenuItem.IsEnabled = false;
                SoundOpenMenuItem.IsEnabled = false;
                UndoMenuItem.IsEnabled = false;
                RedoMenuItem.IsEnabled = false;
                ClearMenuItem.IsEnabled = false;
                PropsAccItem.IsEnabled = false;
                PresetsAccItem.IsEnabled = false;
                CeilingHeightBox.IsEnabled = false;
                FloorMaterialBox.IsEnabled = false;
                RefVolumeSlider.IsEnabled = false;
                RefDepthSlider.IsEnabled = false;
                CeilingMaterialBox.IsEnabled = false;
                PlayButton.IsEnabled = false;
                CancelButton.IsEnabled = true;

                RoomCanvas.MouseUp -= RoomCanvas_MouseUp;
                ((TextBlock)PropsPanel.Children[0]).Text = "Properties";
                PropsPanel.Children.RemoveRange(1, PropsPanel.Children.Count - 1);
                mSelectedRoomObject = null;
                DrawRoom();

                SoundProgressBar.Visibility = Visibility.Visible;
                SoundProgressBar.Value = 0;
                SoundProgressBar.Maximum = mRoom.Sources.Count*mRoom.Listeners.Count*(mRoom.Walls.Count*2+1)+2;
                mReflectionWorker.WorkerReportsProgress = true;
                int num = 0;
                EventHandler reporter= delegate
                {
                    mReflectionWorker.ReportProgress(num++);
                };
                mRoom.CalculationProgress += reporter;

                mReflectionWorker.DoWork += delegate
                {
                    try
                    {
                        mRoom.CalculateSound(mReflectedVolume);
                    }
                    catch (Exception ex)
                    {
                        Dispatcher.Invoke((Action) delegate
                        {
                            if (CancelButton.IsEnabled)
                            {
                               MessageBox.Show(this, "Error occurred during recording process: " + ex.Message);
                                throw ex;
                            }

                        });
                    }

                };
                mReflectionWorker.RunWorkerCompleted += delegate
                {
                    if (!CancelButton.IsEnabled) return;
                    CancelButton.IsEnabled = false;
                    mResultSound = mRoom.GetSoundFromListeners();
                    mResultSound.AdjustVolume(0.75);
                    if (!mReflectionWorker.CancellationPending)
                    {
                        SoundSaveMenuItem.IsEnabled = true;
                        PlayButton.IsEnabled = true;
                    }
                    RecordButton.IsEnabled = true;
                    mRoom.CalculationProgress -= reporter;
                    SoundProgressBar.Visibility = Visibility.Hidden;
                    for (int i = 0; i<buttonNumber-1;i++)
                    {

                        mToolButtons[i].IsEnabled = true;

                    }
                    RoomOpenMenuItem.IsEnabled = true;
                    SoundOpenMenuItem.IsEnabled = true;
                    UndoMenuItem.IsEnabled = true;
                    RedoMenuItem.IsEnabled = true;
                    ClearMenuItem.IsEnabled = true;
                    PropsAccItem.IsEnabled = true;
                    PresetsAccItem.IsEnabled = true;
                    CeilingHeightBox.IsEnabled = true;
                    FloorMaterialBox.IsEnabled = true;
                    RefVolumeSlider.IsEnabled = true;
                    RefDepthSlider.IsEnabled = true;
                    CeilingMaterialBox.IsEnabled = true;

                    RoomCanvas.MouseUp+=RoomCanvas_MouseUp;
                    StatusBlock.Foreground=Brushes.DarkGreen;

                    StatusBlock.Text = mReflectionWorker.CancellationPending?"Recording cancelled":"Recording successfully finished";
                };
                mReflectionWorker.ProgressChanged += (obj,args)=>
                {
                    SoundProgressBar.Value++;
                };
                mReflectionWorker.RunWorkerAsync();
            }
            catch (Exception exception)
            {
                MessageBox.Show(this, "Error occurred during recording process: " + exception.Message);
            }
        }
예제 #9
0
파일: Sound.cs 프로젝트: Earlvik/ArtiStereo
        /// <summary>
        /// Get wave sound data from file
        /// </summary>
        /// <param name="filename">Path to file</param>
        /// <returns></returns>
        public static Sound GetSoundFromWav(string filename)
        {
            FileInfo file = new FileInfo(filename);
            if(!file.Exists || file.Extension.Substring(1)!="wav") throw new ArgumentException("The given file is not an existent wav file");
            Sound sound = new Sound();
            try
            {
                byte[] bytes = File.ReadAllBytes(filename);
                if(bytes[20]!=1 || bytes[21]!=0) throw new ArgumentException("The given file is not in standart WAV format");
                sound.mChannels = bytes[23]*256 + bytes[22];
                sound.mDescretionRate = bytes[27]*16777216 + bytes[26]*65536 + bytes[25]*256 + bytes[24];
                sound.mBitsPerSample = BytesToInt(bytes[34], bytes[35]);
                if (sound.mBitsPerSample == 0) sound.mBitsPerSample = 16;
                int pos = 12;

                while (!(bytes[pos] == 100 && bytes[pos + 1] == 97 && bytes[pos + 2] == 116 && bytes[pos + 3] == 97))
                {
                    pos += 4;
                    int chunkSize = bytes[pos] + bytes[pos + 1]*256 + bytes[pos + 2]*65536 + bytes[pos + 3]*16777216;
                    pos += 4 + chunkSize;
                }
                pos += 8;
                int samples = (bytes.Length - pos)/(sound.mBitsPerSample/8);
                if (sound.mChannels == 2) samples = (samples%2 == 0) ? samples/2 : samples/2 + 1;
                sound.mSound = new float[sound.mChannels][];
                for (int i = 0; i < sound.mChannels; i++)
                {
                    sound.mSound[i] = new float[samples];
                }
                int j = 0;
                sound.mMaxValue = (int) (Math.Pow(256, sound.mBitsPerSample/8)/2);
                while (pos + 1 < bytes.Length)
                {

                    for (int k = 0; k < sound.mChannels; k++)
                    {
                        if (pos + 1 >= bytes.Length) break;
                        if (sound.mBitsPerSample == 16)
                        {
                            sound.mSound[k][j] = (float) BytesToInt(bytes[pos], bytes[pos + 1])/sound.mMaxValue;
                        }
                        else
                        {
                            int curSound = 0;
                            int bytesNum = sound.mBitsPerSample/8;
                            for (int i = 0; i < bytesNum; i++)
                            {
                                byte nextByte = bytes[pos + i];
                                nextByte <<= 8*i;
                                curSound |= nextByte;
                            }
                            if (curSound > sound.mMaxValue + 1)
                            {
                                curSound -= 2*sound.mMaxValue + 1;
                            }
                            sound.mSound[k][j] = (float) curSound/sound.mMaxValue;
                        }

                        pos += (sound.mBitsPerSample/8);
                    }
                    j++;
                }

                return sound;
            }
            catch (Exception e)
            {
                ArgumentException ex = new ArgumentException("The chosen file seems not to be a valid .wav file");
                throw ex;
            }
        }
예제 #10
0
 private void OpenKernelSoundButton_Click(object sender, RoutedEventArgs e)
 {
     OpenFileDialog dialog = new OpenFileDialog { CheckPathExists = true, CheckFileExists = true, Filter = "Wave Sound Files (*.wav)|*.wav" };
     bool? result = dialog.ShowDialog();
     if (result == true)
     {
         try
         {
             mKernelSound = Sound.GetSoundFromWav(dialog.FileName);
         }
         catch (Exception exception)
         {
             MessageBox.Show("Error occured during opening: " + exception.Message);
             ConvolveButton.IsEnabled = false;
             return;
         }
         KernelSeries.DataContext = mKernelSound.ToKeyValuePairs(0);
         MessageBox.Show("Successfully opened " + dialog.FileName, "Sound Open", MessageBoxButton.OK);
         if (mConvolveBaseSound != null)
         {
             if (CheckSound(mKernelSound, mConvolveBaseSound))
             {
                 ConvolveButton.IsEnabled = true;
                 ConvolutionStatusBlock.Foreground=Brushes.Green;
                 ConvolutionStatusBlock.Text = "Everything is OK. You can start convolution.";
             }
             else
             {
                 ConvolveButton.IsEnabled = false;
                 ConvolutionStatusBlock.Foreground = Brushes.Red;
                 ConvolutionStatusBlock.Text =
                     "Chosen sound and impulse response should have same sound parameters";
             }
         }
        KernelSoundBlock.Text = dialog.SafeFileName;
     }
 }
예제 #11
0
        private void PlayButton_OnChecked(object sender, RoutedEventArgs e)
        {
            if (mResultSound != null)
            {
                const string filename = "~temp_sound.wav";
                Sound resultTwoCh = new Sound(2,mResultSound.DiscretionRate,mResultSound.BitsPerSample);
                resultTwoCh.Add(mResultSound,0,0,0);
                resultTwoCh.Add(mResultSound, mResultSound.Channels > 1 ? 1 : 0, 1, 0);
                resultTwoCh.CreateWav(filename);
                File.SetAttributes(filename,File.GetAttributes(filename)|FileAttributes.Hidden);
                mPlayer = new SoundPlayer(filename);
                mPlayer.Load();
                mPlayer.PlayLooping();

            }
        }
예제 #12
0
        private void ConvolveButton_Click(object sender, RoutedEventArgs e)
        {
            BackgroundWorker worker =new BackgroundWorker();
            ConvolutionStatusBlock.Text = "In progress...";
            ConvolveButton.IsEnabled = false;
            OpenBaseSoundButton.IsEnabled = false;
            OpenKernelSoundButton.IsEnabled = false;
            SaveConvolvedButton.IsEnabled = false;
            worker.DoWork += delegate
            {
                if (mKernelSound.Channels < mConvolveBaseSound.Channels)
                {
                    for (int i = 0; i < mConvolveBaseSound.Channels; i++)
                    {
                        mConvolveBaseSound.Convolve(mKernelSound, i, 0);
                    }
                }
                else
                {
                    if (mKernelSound.Channels > mConvolveBaseSound.Channels)
                    {
                        Sound TempSound = new Sound(mKernelSound.Channels,mConvolveBaseSound.DiscretionRate,mConvolveBaseSound.BitsPerSample);
                        for (int i = 0; i < mKernelSound.Channels; i++)
                        {
                           TempSound.Add(mConvolveBaseSound,0,i,0);
                        }
                        mConvolveBaseSound = TempSound;
                    }
                    for (int i = 0; i < mConvolveBaseSound.Channels; i++)
                    {
                        mConvolveBaseSound.Convolve(mKernelSound, i, i);
                    }
                }
                mConvolveResultSound = mConvolveBaseSound;
                mConvolveResultSound.AdjustVolume(0.8);
                mConvolveBaseSound = null;
                mKernelSound = null;

            };
            worker.RunWorkerCompleted += delegate
            {
                BaseSoundBlock.Text = KernelSoundBlock.Text = "No file loaded";
                ConvolutionStatusBlock.Text = "Convolution finished. Feel free to save result";
                mConvolveBaseSound = null;
                mKernelSound = null;
                if (mConvolveResultSound == null)
                {
                    ConvolutionStatusBlock.Foreground=Brushes.Red;
                    ConvolutionStatusBlock.Text = "NMath library needs to be installed for convolution";
                }
                OpenBaseSoundButton.IsEnabled = true;
                OpenKernelSoundButton.IsEnabled = true;
                SaveConvolvedButton.IsEnabled = true;
            };
            worker.RunWorkerAsync();
        }
예제 #13
0
 private bool CheckSound(Sound first, Sound second)
 {
     return (first.BitsPerSample == second.BitsPerSample);
 }
예제 #14
0
 private void SoundOpenMenuItem_Click(object sender, RoutedEventArgs e)
 {
     OpenFileDialog dialog = new OpenFileDialog {CheckPathExists = true, CheckFileExists = true, Filter = "Wave Sound Files (*.wav)|*.wav"};
     bool? result = dialog.ShowDialog();
     if (result == true)
     {
         try
         {
             mBaseSound = Sound.GetSoundFromWav(dialog.FileName);
         }
         catch (Exception exception)
         {
             MessageBox.Show("Error occured during opening: " + exception.Message);
             return;
         }
         RecordButton.IsEnabled = true;
         MessageBox.Show("Successfully opened " + dialog.FileName,"Sound Open",MessageBoxButton.OK);
         foreach (SoundPoint source in mRoom.Sources)
         {
             source.Sound = mBaseSound;
         }
         FileNameBlock.Text = "Source: "+dialog.SafeFileName;
         SoundSeries.DataContext = mBaseSound.ToKeyValuePairs(0);
        // Timeline.Visibility = Visibility.Visible;
         DrawRoom();
     }
 }
예제 #15
0
        public void PrimaryReflectionsComplexTest()
        {
            AS.Wall.Material mat = AS.Wall.Material.OakWoodCarpeted;
            AS.Room room = new AS.Room();
            room.FloorMaterial = AS.Wall.Material.Brick;
            room.CeilingMaterial = AS.Wall.Material.OakWood;
            room.CeilingHeight = 2;
            room.AddWall(new AS.Wall(0, 0, 4, 0, mat));
            room.AddWall(new AS.Wall(0, 0, 0, 10, mat));
            room.AddWall(new AS.Wall(4, 0, 4, 10, mat));
            room.AddWall(new AS.Wall(0, 10, 4, 10, mat));
            AS.SoundPoint source = new AS.SoundPoint(2, 1);
            source.Sound = AS.Sound.GetSoundFromWav(@"D:\Whistling.wav");
            room.AddSource(source);
            room.AddListener(new AS.ListenerPoint(1, 8,new AS.Line(0,0,-1,0),AS.ListenerPoint.Cardioid));
            room.AddListener(new AS.ListenerPoint(3, 8, new AS.Line(0,0,1,0),AS.ListenerPoint.Cardioid ));

            room.CalculateSound();
            AS.Sound sound = new AS.Sound(2,source.Sound.DiscretionRate,source.Sound.BitsPerSample);
            sound.Add(room.Listeners[1].Sound,0,0,0);
            sound.Add(room.Listeners[0].Sound,0,1,0);
            sound.AdjustVolume(0.75);
            //sound.SetVolume(0.6,0);
            //sound.SetVolume(0.6,1);
            sound.CreateWav(@"D:\Result.wav");
        }
예제 #16
0
        public void PrimaryReflectionsHugeTest()
        {
            AS.Wall.Material mat = AS.Wall.Material.Brick;
            AS.Room room = new AS.Room();
            room.FloorMaterial = AS.Wall.Material.Brick;
            room.CeilingMaterial = AS.Wall.Material.OakWood;
            room.CeilingHeight = 2;
            room.AddWall(new AS.Wall(0,5,10,0,mat));
            room.AddWall(new AS.Wall(10,0,20,5,mat));
            room.AddWall(new AS.Wall(20,5,20,45,mat));
            room.AddWall(new AS.Wall(20,45,0,45,mat));
            room.AddWall(new AS.Wall(0,45,0,5, mat));
            AS.SoundPoint source = new AS.SoundPoint(10,40);
            source.Sound = AS.Sound.GetSoundFromWav(@"D:\dirac.wav");
            room.AddSource(source);
            room.AddListener(new AS.ListenerPoint(9,4));
            room.AddListener(new AS.ListenerPoint(11,4));

            room.CalculateSound();
            AS.Sound sound = new AS.Sound(2, source.Sound.DiscretionRate, source.Sound.BitsPerSample);
            sound.Add(room.Listeners[1].Sound, 0, 0, 0);
            sound.Add(room.Listeners[0].Sound, 0, 1, 0);
            sound.AdjustVolume(0.75);
            //sound.SetVolume(0.6, 0);
            //sound.SetVolume(0.6, 1);
            sound.CreateWav(@"D:\diracR.wav");
            Console.WriteLine(GC.GetTotalMemory(false)/(1024*1024)+"");
        }