У меня запутанная проблема с текущим проектом.По сути, я анализирую байтовый файл MIDI-файла (да, я должен сделать это так).MIDI-файлы структурированы таким образом, что данные для любого данного события в дорожке передаются через серию байтов, называемых «сообщением».MIDI-устройство знает, какой тип сообщения, на основе кода состояния, который составляет 1-3 байта в «сообщении», которые имеют определенные идентификаторы для определенных функций.
Мне нужно иметь возможность просматривать данные файла MIDI и записывать каждое «сообщение» как отдельный объект, чтобы я мог поместить их в последовательность для последующего использования.Проблема, с которой я сталкиваюсь, заключается в том, что по мере прохождения данных мне нужен эффективный способ прочитать каждый код состояния и сопоставить его с функцией, которую я написал, которая обрабатывает данные для этого типа сообщения.Сейчас я пытаюсь сделать следующее:
Во-первых, в любой заданной точке общего файла MIDI я просматриваю следующие 3 байта и сравниваю их со своим списком всех возможных трехбайтовых MIDI-файлов.коды состояния.Вот моя первая проблема.Для всех 3-байтовых кодов состояния (которые эквивалентны 6 шестнадцатеричным цифрам , которые часто используются при редактировании MIDI), 5-8-ые биты (второй шестнадцатеричный код)цифра) указывает канал MIDI, на который влияет текущее сообщение, которое является переменным и непредсказуемым.Поскольку я не могу предсказать канал, мне нужно воспринимать его как универсальное значение.Другими словами, мне нужно как-то уметь брать 6 цифр и игнорировать 2-ю, когда я сравниваю их со своим списком кодов.Я не думаю, что я объяснил это хорошо, поэтому вот пример:
6 шестнадцатеричный код внутри файла: Bn7800
, где n
- номер канала
Список 6Коды цифр: ['Bn7800','Bn7900','FF2001','FF2F00',...]
Мне нужно найти в этом списке правильный код, игнорируя 2-ю цифру, поскольку я не могу сказать, что это за время.
Мой другойПроблема в том, что, получив этот код, мне нужно вызвать конкретную функцию, написанную мной, которая обрабатывает этот код состояния.Я назвал все функции после кода состояния, которому они соответствуют, но проблема в том, что я не знаю, как взять строку, найденную в списке выше, и использовать ее для вызова функции.Например:
Мне нужно: Bn7800
В списке я нахожу это!Поэтому я храню его как новую переменную с именем stat_code = 'Bn7800'
.Но тогда я не могу вызвать свою функцию таким образом -> self.stat_code(data)
, потому что stat_code
- это не имя функции, которую я хочу.Я хочу, чтобы функция была названа в честь значения из stat_code
.
Я не уверен, как можно вызвать функцию, основываясь на значении хранимой переменной.
Извините, если это сбивает с толку, мне трудно объяснить полностью, не пытаясь объяснить всю структуру файла MIDI.Пожалуйста, задавайте мне вопросы, если что-то неясно.Спасибо!
РЕДАКТИРОВАТЬ: Вот часть кода:
self.event_status_codes = {'ff0002': ff_00_02,'ff01': ff_01,'ff02': ff_02,'ff03': ff03,'ff04': ff_04,'ff05': ff_05,'ff06': ff_06,'ff07': ff_07,'ff2001': ff_20_01,'ff2f00': ff_2f_00,'ff5103': ff_51_03,'ff5405': ff_54_05,'ff5804': ff_58_04,'ff5902': ff_59_02,'ff7f': ff_7f,'8n': _8n,'9n': _9n,'an': an,'bn': bn,'cn': cn,'dn': dn,'en': en,'bn7800': bn_78_00,'bn7900': bn_79_00,'bn7a': bn_7a,'bn7b00': bn_7b_00,'bn7c00': bn_7c_00,'bn7d00': bn7d00,'bn7e': bn_7e,'bn7f00': bn_7f_00,'f0': f0,'f7': f7}
if track_data[hbc:hbc+3] in self.event_status_codes:
status_code = track_data[hbc:hbc+3]
self.status_code(track_data)
Для справки: track_data
- это необработанная шестнадцатеричная последовательность, которую я анализирую, и hbc
простой указатель, который перебирает файл по одной шестнадцатеричной цифре за раз.Я разместил полный словарь кодов состояния, но сейчас я в основном обеспокоен 3-значными, потому что они обычно указывают номер канала.Кроме того, это технически словарь Python, потому что мне пришлось называть каждую соответствующую функцию чем-то немного отличающимся от фактического кода, чтобы сделать его читаемым и функциональным, чтобы можно было игнорировать значения каждого ключа в словаре.