Desktop software developer
Информация
- В рейтинге
- Не участвует
- Откуда
- Санкт-Петербург, Санкт-Петербург и область, Россия
- Дата рождения
- Зарегистрирован
- Активность
Специализация
Software Developer, Test Automation Engineer
Lead
C#
.NET
Git
Selenium
Test Automation
Слишком категоричное заявление. Из моего опыта обращений пользователей это не так. Хотя, подтверждаю, задача одна из популярных.
Совершенно верно, и VSTi это уже про генерацию аудио (собственно, звука). VSTi забирает данные из MIDI Input и генерирует звук. MIDI это только про команды для синтезатора (аппратного, программного, VSTi и иже с ними), MIDI абсолютно никак с генерацией звука не связан сам по себе.
Думаю, ваша проблема была какой-то иной или я чего-то не понял. Что мешает озвучивать ваш синтезатор (аппаратный, как я понимаю, речь не про генерацию MIDI из программы) любым VSTi? Зачем тут какой-то "низкоуровневый звук"?
Если же речь про озвучивание генерируемого программой MIDI, то ситуация стандартная и решается не менее стандартно через виртуальные устройства. Как я и писал выше, virtual cables это называется. Из наиболее популярных и бесплатных, наверное, loopMIDI:
создаёте в loopMIDI устройство с именем X;
выводите MIDI плейбек на этот X;
забираете данные из X в любом нужном вам VSTi (т.е. у инструмента указываете MIDI Input = X).
Хорошее замечание, спасибо.
Принимаю. Но для пользователей функция, от того алгоритма зависящаая, работает верно.
Вы путаете MIDI и Audio. MIDI playback никогда не будет без таймера. Audio будет, звук выводится на аудио-устройства посредством буфера.
Любой VSTi имеет параметр MIDI input. Это MIDI-устройство, откуда принимать даные. Стандартная практика вывода программного MIDI в VST-инструмент — виртуальные устройства (aka virtual cables). DryWetMIDI предоставляет возможность выводить MIDI.
Процент задач, в которых нужно вникать в низкоуровневую реализацию намного меньше прикладных задач, в которых получить ноты или выполнить их квантизацию есть насущные проблемы.
Разумеется, каждый сам выбирает себе инструмент, который ему больше нравится.
Возвращаясь в русло статьи: в обеих этих библиотеках нет предлагаемого вами подхода — каждый класс класть в отдельное пространство имён. Повторюсь, вы первый, кто такое практикует. Это любопытно, и в любом случае спасибо за комментарий.
Я за критику, но конструктивную. В прошлой статье были комментарии, указывающие на минусы подхода с кастомными структурами. Очень благодарен этим замечаниям, я их добавил в статью даже.
Да, об этом сказано в статье:
По поводу
не согласен категорически. Мало того, что я вообще в первый раз вижу отдельные пространства имён под каждый класс (пользователи за это будут вам очень "благодарны"), так ещё и логичного в этом ничего не вижу (AllNoteOff это так-то событие Control Change с определёнными параметрами).
Опять же, не могу согласиться. Да, это протокол передачи данных. Но его активно используют музыканты, например, вставляя в DAW. К слову, DAW пары Note On/Off объединяют, внезапно, в ноты в пиано ролле, потому что, как я и говорил, музыканты не работают в терминах MIDI.
Да и большое число пользователей, вопросов и обращений подтверждают, что API библиотеки сделан более или менее правильно. Библиотека ведь не запрещает вам использовать и "сырые" MIDI-события. Архитектура DryWetMIDI слоистая, есть и слой с абстракциями в терминах MIDI, можно и ими пользоваться. А можно и более высокоуровневыми.
Ну так чтобы сделать импорт, понадобится вся та кухня, что есть сейчас по работе с MIDI. Мне кажется, вы полагаете, что библиотека предоставляет только абстракции высокого уровня. Это не так. Даже в README проекта я об этом явно говорю:
Спасибо большое за полезный комментарий, добавил информацию в статью.
Да, соглашусь.
Вообще, в библиотеке касательно вашего подхода есть несколько методов, например:
или
Длиннее, чем
enum
, но идея та же, и она верная: по имени ноты и октаве получить ноту/её номер.Номер ноты и скорость нажатия лишь примеры, в MIDI намного больше таких сущностей.
Ну и
enum
не спасёт в случае вычисления значения по какой-то формуле. Придётся результат приводить к этомуenum
'у. А что если результат есть число, не принадлежащее перечисление? C# всё равно выполнит приведение, есть уenum
'ов такая особенность. И пойдёт гулять по программе невалидное значение.Мне кажется, вы невнимательно прочли статью.
Всё верно, и такое преобразование у меня явное. Также, как
long
кint
. Посмотрите на код ещё раз.explicit operator
это оно. Вы же пытаетесь доказать, что у меня исключение в неявном преобразование, но это не так.Спасибо, добавил в статью информацию.
Спасибо.
Внутри моей библиотеки у
SevenBitNumber
/FourBitNumber
есть методыParse
/TryParse
. Ну и в целом, исключение при приведении типа или исключение при валидации параметра сообщает нам об одном и том же — значение невалидно. В MS это не запрещается, просто преобразование должно быть явным:Касательно этого утверждения
не соглашусь. Как раз про неявное знать необязательно. На то оно и неявное, что никаких рисков нет. Из
SevenBitNumber
преобразование вbyte
не сопряжено ни с какими последствиями, поэтому оно неявное. Вероятно, вы имели в виду явное всё же.Да, библиотека поддерживает старые версии языка, но для полноты добавил информацию в статью, спасибо.
Чем не устраивает, написано в следующем абзаце в статье:
Спасибо.
Статья не про локализацию, а про подход. Локализовывать здорово, но в библиотеке я этим не занимаюсь, считаю, что английского вполне хватит. Если честно, по пальцам пересчитать библиотеки, которые выводят локализованные сообщения об ошибках.
Да, это минус. С другой стороны, если вы получите сообщение с именем параметра, это всё равно ничего вам не скажет о том, почему в него попало невалидное значение.
Если речь про отладку и сложные выражения, да, есть такой момент, дописал в статью.
Верно. Чтобы сделать статью лучше, покажите, пожалуйста, пример, я с радостью добавлю.
Согласен. В статье просто пример подхода. Хотя, признаюсь, грешу иногда такими малозначимыми сообщениями. Нужно будет пройтись по библиотеке проверить. Спасибо!
Спасибо, вы навели меня на мысль, дополнил раздел Минусы. Но, кажется, вы говорите о чём-то другом. Можете, пожалуйста, показать пример, где возникают сложности? Это я про ваш пункт 2.
Спасибо, добавил в статью. Правда, работать это будет только до тех пор, пока мы не захотим использовать слева
var
.Теперь стало понятно, вы про внутренний метод в библиотеке. Да, тут коррекции возможны. Но публичный метод, который доступен пользователям, использует этот код с доработками, поэтому зависаний не будет.
Покажите, пожалуйста, ваш код, как вы проверяли. Если вы говорите про приближение действительного числа рациональным, речь же про метод FromDouble? Если так, то там невозможно получить зависание, как я уже упомянул выше. Более того, вам не нужно ничего делать с количеством итераций, просто не указывайте и всё будет работать с настройками по умолчанию :-)
Я к багам отношусь всегда серьёзно, поэтому, если ошибка есть, буду рад исправить. Но для этого мне нужно знать, как её поймать.
Пусть будет дело вкуса.
За пару миллисекунд получил ответ
7/9
. Никакого бесконечного цикла быть тут не может. Если вы посмотрите в настройки, там, помимо эпсилона на дробную часть и ограничения по точности приближения, есть ещё ограничение по количеству итераций. Это тот рубильник, который и призван спасти от каких-либо циклов и зависаний. Всё же лучше сперва проверять перед тем, как "находить ошибку" ;-)А кроме того стоит уровень статьи Средний. Уровень это про текст статьи, но в статье (если это вообще статьёй можно назвать) нет ничего требующего навыков отличных от навыка чтения.
Также замечу, что существует сайт Code Review Stack Exchange, созданный специально с целью помогать ревьювить код и помогать с кодом в плане архитетуры, стиля и всего такого. Я подозреваю, что автору нужно было написать туда.