Написание гитарного тюнера на язык с#

Заказать уникальную курсовую работу
Тип работы: Курсовая работа
Предмет: Программирование
  • 59 59 страниц
  • 12 + 12 источников
  • Добавлена 13.07.2023
1 000 руб.
  • Содержание
  • Часть работы
  • Список литературы
ВВЕДЕНИЕ 7
1 Техническое задание 8
1.1 Основания для разработки 8
1.2 Назначение разработки 8
1.3 Требования пользователя к программному изделию 8
1.3.1 Исследование предметной области 8
1.3.2 Требования к функциональным характеристикам 9
1.3.2.1 Прецеденты 9
1.3.2.2 Сценарии прецедентов программного изделия 15
1.3.3 Требования к интерфейсу пользователей программного изделия 18
1.3.4 Требования к архитектуре программного изделия 19
1.3.5 Требования к надежности 20
1.3.6 Условия эксплуатации 20
1.3.7 Требования к составу и параметрам технических средств 20
1.3.8 Требования к информационной и программной совместимости 20
1.4 Требования к программной документации 21
1.5 Стадии и этапы разработки 21
1.6 Порядок контроля и приемки 21
2 Технический проект 22
2.1 Словарь предметной области программного изделия 22
2.2 Моделирование вариантов использования 23
2.3 Концептуальная модель предметной области и схемы алгоритмов 25
3 Рабочий проект 29
3.1 Модули и объекты интерфейса пользователя 29
3.1.1 Описание объектов интерфейса программы 29
3.1.2 Тестирование интерфейса программной среды 34
3.2 Тестовые наборы для отладки работы программы. 37
ЗАКЛЮЧЕНИЕ 40
CПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 41
ПРИЛОЖЕНИЕ A 42

Фрагмент для ознакомления

Так, частотный диапазон микрофона ELECTRO-VOICE ND 367-S имеет пределы 25−20000 Гц, SHURE SM81 — 20−20000 Гц, AKG D112 — 20−17000 Гц, SENNHEISER E604 — 20−18000 Гц.Чувствительность — способность микрофона уловить тихий звуковой сигнал и преобразовать его в электрическую волну. Измеряется показатель в децибелах (дБ) или милливольтах на паскаль (мВ/Па), чем ближе он к нулю в децибелах — самому низкому значению, которое способно уловить человеческое ухо — тем выше чувствительность микрофона. В милливольтах на паскаль, наоборот: чем цифра больше, тем лучше. Например, у очень чувствительного конденсаторного микрофона-пушки SENNHEISER MKH-1 она достигает 40 мВ/Па, а у классического динамического SHURE BETA 58 — 2,6 мВ/Па. Выбирая чувствительность микрофона, нужно особенно оценить обстановку, где предполагается его использовать. Студия звукозаписи, где отсутствуют посторонние шумы, идеальное место для высокочувствительного устройства, а вот для концерта или уличного выступления лишние звуки будут создавать ненужный фон и раздражающие помехи.Для удобства настройки рекомендуется использовать стойку для микрофона или специальное приспособление для фиксации микрофона:Рисунок 3.2  Крепление на гитару для микрофонаРезультат тестирования программы тюнера представлен на рис. 3.3-3.6.Рисунок 3.3 Звучание открытой струны 6Рисунок 3.4 Звучание открытой струны 5Рисунок 3.5 Звучание открытой струны 4ЗАКЛЮЧЕНИЕВ результате выполнения курсовой работы была разработана программа гитарного тюнера. Разработанная программа позволяет пользователю настраивать музыкальный инструмент, с оптимизацией интерфейса под настройку гитары.В процессе выполнения курсовой работы на основе исследования предметной области приложения были определены требования к приложению. Для реализации требований к приложению разработана архитектура приложения; разработаны алгоритмы и программные модули для реализации определения ноты звучания; спроектирован и реализован графический интерфейс программы; проведено функциональное тестирование приложения. Все требования, объявленные в техническом задании, были полностью реализованы в данном программном продукте.Все задачи, поставленные в начале разработки проекта, были решены.Таким образом, цель работы достигнута.CПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВБелик, А. Г. Проектирование и архитектура программных систем : учебное пособие / А. Г. Белик, В. Н. Цыганенко. – Омск : ОмГТУ, 2016. – 96 с. – ISBN 978-5-8149-2258-8. – Текст : непосредственный.Прайс МаркC# 9 и .NET 5. Разработка и оптимизация - Питер. 2022 – 832cДжепикс Филипп, Троелсен ЭндрюЯзык программирования C# 9 и платформа .NET 5: основные принципы и практики программирования. - М.: Диалектика / Вильямс, 2022. - 1392 cМартин, Р. Чистая архитектура. Искусство разработки про-граммного обеспечения / Р. Мартин ; пер. с англ. А. Кисилева. – Санкт-Петербург : Питер, 2018. – 351 с. – ISBN 978-5-4461-0772-8. – Текст : непосредственный.Шкляр, М. Ф. Основы научных исследований : учебное пособие / М. Ф. Шкляр. – 7-е изд. – Москва : Дашков и К° , 2019. – 208 с. – ISBN 978-5-394-03375-9. – URL: https://znanium.com/catalog/product/1093533 (дата обращения: 17.09.2020). – Текст : электронный.Рихтер ДжеффриCLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#. 4-е изд. Питер. - М., 2022 – 896 сГамма Эрих, Хелм Ричард, Джонсон Роберт, Влиссидес ДжонПаттерны объектно-ориентированного проектирования: Питер, 2022 448сБитти Джой, Вигерс Карл И.Разработка требований к программному обеспечению БХВ, 2019 – 736 сБПФ (Быстрое преобразование Фурье) - URL : https://www.kipis.ru/info/index.php?ELEMENT_ID=40417Таблица соотношения нот и частотURL:https://nch-nch.ru/frequency/ 2021гН. Н. Андреев, С. П. Коновалов, Н. М. ПанюнинМатематическая СоставляющаяМ. : Фонд «Математические этюды», 2019. — 367 с.Руководство по программированию для Direct3D 122023URL:https://learn.microsoft.com/ru-ru/windows/win32/direct3d12/directx-12-programming-guideПРИЛОЖЕНИЕAИсходный код программы гитарного тюнера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;namespace KursTuner{ public partial class MainForm : Form { bool isListenning = false; public bool IsListenning { get { return isListenning; } } public MainForm() { InitializeComponent(); } private void closeButton_Click(object sender, EventArgs e) { Close(); } FrequencyInfoSource frequencyInfoSource; private void StopListenning(){if (isListenning) { isListenning = false; frequencyInfoSource.Stop(); frequencyInfoSource.FrequencyDetected -= new EventHandler(frequencyInfoSource_FrequencyDetected); frequencyInfoSource = null; } } private void StartListenning(SoundCaptureDevice device) { isListenning = true; frequencyInfoSource = new SoundFrequencyInfoSource(device); frequencyInfoSource.FrequencyDetected += new EventHandler(frequencyInfoSource_FrequencyDetected); frequencyInfoSource.Listen(); } void frequencyInfoSource_FrequencyDetected(object sender, FrequencyDetectedEventArgs e) { if (InvokeRequired) { BeginInvoke(new EventHandler(frequencyInfoSource_FrequencyDetected), sender, e); } else { UpdateFrequecyDisplays(e.Frequency); } } private void UpdateFrequecyDisplays(double frequency) { if (frequency > 0) { tbCurrentFreq.Enabled = true; tbCurrentFreq.Text = frequency.ToString("f3"); double closestFrequency; string noteName; FindClosestNote(frequency, out closestFrequency, out noteName); tbNote.Enabled = true; tbNote.Text = noteName; } else { tbCurrentFreq.Enabled = false; tbNote.Enabled = false; } } static string[] NoteNames = {"A", "A#", "B/H", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#" }; static double ToneStep = Math.Pow(2, 1.0 / 12); private void FindClosestNote(double frequency, out double closestFrequency, out string noteName) { const double AFrequency = 440.0; const int ToneIndexOffsetToPositives = 120; int toneIndex = (int)Math.Round( Math.Log(frequency / AFrequency, ToneStep) ); noteName = NoteNames[(ToneIndexOffsetToPositives + toneIndex) % NoteNames.Length]; closestFrequency = Math.Pow(ToneStep, toneIndex) * AFrequency; } private void bnSettings_Click(object sender, EventArgs e) { SoundCaptureDevice device = null; using (SelectDeviceForm form = new SelectDeviceForm()) { if (form.ShowDialog() == DialogResult.OK) { device = form.SelectedDevice; } } if (device != null) { StartListenning(device); UpdateListenStopButtons(); } } private void UpdateListenStopButtons() { bnSettings.Enabled = !isListenning; } private void bnStop_Click(object sender, EventArgs e) { StopListenning(); UpdateListenStopButtons(); } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (IsListenning) { StopListenning(); } } }}FftAlgorithm.csusing System;namespace KursTuner{ ///

/// Cooley-Tukey FFT algorithm. /// public static class FftAlgorithm { /// /// Calculates FFT using Cooley-Tukey FFT algorithm. /// /// input data /// spectrogram of the data /// /// If amount of data items not equal a power of 2, then algorithm /// automatically pad with 0s to the lowest amount of power of 2. /// public static double[] Calculate(double[] x) { int length; int bitsInLength; if (IsPowerOfTwo(x.Length)) { length = x.Length; bitsInLength = Log2(length) - 1; } else { bitsInLength = Log2(x.Length); length = 1 << bitsInLength; // the items will be pad with zeros } // bit reversal ComplexNumber[] data = new ComplexNumber[length]; for (int i = 0; i < x.Length; i++) { int j = ReverseBits(i, bitsInLength); data[j] = new ComplexNumber(x[i]); } // Cooley-Tukey for (int i = 0; i < bitsInLength; i++) { int m = 1 << i; int n = m * 2; double alpha = -(2 * Math.PI / n); for (int k = 0; k < m; k++) { // e^(-2*pi/N*k) ComplexNumber oddPartMultiplier = new ComplexNumber(0, alpha * k).PoweredE(); for (int j = k; j < length; j += n) { ComplexNumber evenPart = data[j]; ComplexNumber oddPart = oddPartMultiplier * data[j + m]; data[j] = evenPart + oddPart; data[j + m] = evenPart - oddPart; } } } // calculate spectrogram double[] spectrogram = new double[length]; for (int i = 0; i < spectrogram.Length; i++) { spectrogram[i] = data[i].AbsPower2(); } return spectrogram; } /// /// Gets number of significat bytes. /// /// Number /// Amount of minimal bits to store the number. private static int Log2(int n) { int i = 0; while (n > 0) { ++i; n >>= 1; } return i; } /// /// Reverses bits in the number. /// /// Number /// Significant bits in the number. /// Reversed binary number. private static int ReverseBits(int n, int bitsCount) { int reversed = 0; for (int i = 0; i < bitsCount; i++) { int nextBit = n & 1; n >>= 1; reversed <<= 1; reversed |= nextBit; } return reversed; } /// /// Checks if number is power of 2. /// /// number /// true if n=2^k and k is positive integer private static bool IsPowerOfTwo(int n) { return n > 1 && (n & (n - 1)) == 0; } }}FrequencyUtils.csusing System;using System.Collections.Generic;using System.Linq;using System.Text;namespace KursTuner{ /// /// Utils that helps to detect the fundumental frequency. /// static class FrequencyUtils { /// /// Finds fundamental frequency: calculates spectrogram, finds peaks, analyzes /// and refines frequency by diff sample values. /// /// The sounds samples data /// The sound sample rate /// The min useful frequency /// The max useful frequency /// Found frequency, 0 - otherwise internal static double FindFundamentalFrequency(double[] x, int sampleRate, double minFreq, double maxFreq) { double[] spectr = FftAlgorithm.Calculate(x); int usefullMinSpectr = Math.Max(0, (int)(minFreq * spectr.Length / sampleRate)); int usefullMaxSpectr = Math.Min(spectr.Length, (int)(maxFreq * spectr.Length / sampleRate) + 1); // find peaks in the FFT frequency bins const int PeaksCount = 5; int[] peakIndices; peakIndices = FindPeaks(spectr, usefullMinSpectr, usefullMaxSpectr - usefullMinSpectr, PeaksCount); if (Array.IndexOf(peakIndices, usefullMinSpectr) >= 0) { // lowest usefull frequency bin shows active // looks like is no detectable sound, return 0 return 0; } // select fragment to check peak values: data offset const int verifyFragmentOffset = 0; // ... and half length of data int verifyFragmentLength = (int)(sampleRate / minFreq); // trying all peaks to find one with smaller difference value double minPeakValue = Double.PositiveInfinity; int minPeakIndex = 0; int minOptimalInterval = 0; for (int i = 0; i < peakIndices.Length; i++) { int index = peakIndices[i]; int binIntervalStart = spectr.Length / (index + 1), binIntervalEnd = spectr.Length / index; int interval; double peakValue; // scan bins frequencies/intervals ScanSignalIntervals(x, verifyFragmentOffset, verifyFragmentLength, binIntervalStart, binIntervalEnd, out interval, out peakValue); if (peakValue < minPeakValue) { minPeakValue = peakValue; minPeakIndex = index; minOptimalInterval = interval; } } return (double)sampleRate / minOptimalInterval; } private static void ScanSignalIntervals(double[] x, int index, int length, int intervalMin, int intervalMax, out int optimalInterval, out double optimalValue) { optimalValue = Double.PositiveInfinity; optimalInterval = 0; // distance between min and max range value can be big // limiting it to the fixed value const int MaxAmountOfSteps = 30; int steps = intervalMax - intervalMin; if (steps > MaxAmountOfSteps) steps = MaxAmountOfSteps; else if (steps <= 0) steps = 1; // trying all intervals in the range to find one with // smaller difference in signal waves for (int i = 0; i < steps; i++) { int interval = intervalMin + (intervalMax - intervalMin) * i / steps; double sum = 0; for (int j = 0; j < length; j++) { double diff = x[index + j] - x[index + j + interval]; sum += diff * diff; } if (optimalValue > sum) { optimalValue = sum; optimalInterval = interval; } } } private static int[] FindPeaks(double[] values, int index, int length, int peaksCount) { double[] peakValues = new double[peaksCount]; int[] peakIndices = new int[peaksCount]; for (int i = 0; i < peaksCount; i++) { peakValues[i] = values[peakIndices[i] = i + index]; } // find min peaked value double minStoredPeak = peakValues[0]; int minIndex = 0; for (int i = 1; i < peaksCount; i++) { if (minStoredPeak > peakValues[i]) minStoredPeak = peakValues[minIndex = i]; } for (int i = peaksCount; i < length; i++) { if (minStoredPeak < values[i + index]) { // replace the min peaked value with bigger one peakValues[minIndex] = values[peakIndices[minIndex] = i + index]; // and find min peaked value again minStoredPeak = peakValues[minIndex = 0]; for (int j = 1; j < peaksCount; j++) { if (minStoredPeak > peakValues[j]) minStoredPeak = peakValues[minIndex = j];} } } return peakIndices; } }}

1. Белик, А. Г. Проектирование и архитектура программных систем : учебное пособие / А. Г. Белик, В. Н. Цыганенко. – Омск : ОмГТУ, 2016. – 96 с. – ISBN 978-5-8149-2258-8. – Текст : непосредственный.
2. Прайс Марк C# 9 и .NET 5. Разработка и оптимизация - Питер. 2022 – 832c
3. Джепикс Филипп, Троелсен Эндрю Язык программирования C# 9 и платформа .NET 5: основные принципы и практики программирования. - М.: Диалектика / Вильямс, 2022. - 1392 c
4. Мартин, Р. Чистая архитектура. Искусство разработки про-граммного обеспечения / Р. Мартин ; пер. с англ. А. Кисиле¬ва. – Санкт-Петербург : Питер, 2018. – 351 с. – ISBN 978-5-4461-0772-8. – Текст : непосредственный.
5. Шкляр, М. Ф. Основы научных исследований : учебное пособие / М. Ф. Шкляр. – 7-е изд. – Москва : Дашков и К° , 2019. – 208 с. – ISBN 978-5-394-03375-9. – URL: https://znanium.com/catalog/product/1093533 (дата обращения: 17.09.2020). – Текст : электронный.
6. Рихтер Джеффри CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#. 4-е изд. Питер. - М., 2022 – 896 с
7. Гамма Эрих, Хелм Ричард, Джонсон Роберт, Влиссидес Джон Паттерны объектно-ориентированного проектирования: Питер, 2022 448с
8. Битти Джой, Вигерс Карл И. Разработка требований к программному обеспечению БХВ, 2019 – 736 с
9. БПФ (Быстрое преобразование Фурье) - URL : https://www.kipis.ru/info/index.php?ELEMENT_ID=40417
10. Таблица соотношения нот и частот URL: https://nch-nch.ru/frequency/ 2021г
11. Н. Н. Андреев, С. П. Коновалов, Н. М. Панюнин Математическая Составляющая М. : Фонд «Математические этюды», 2019. — 367 с.
12. Руководство по программированию для Direct3D 12 2023 URL: https://learn.microsoft.com/ru-ru/windows/win32/direct3d12/directx-12-programming-guide