Стек клавиатуры обрабатывает несколько типов запросов. В данной курсовой работе необходимо рассмотреть только IRP типа IRP_MJ_READ, которые несут с собой коды клавиш. Генератором этих IRP является поток необработанного ввода RawInputThread системного процесса csrcc.exe. Этот поток открывает объект «устройство» драйвера класса клавиатуры для эксклюзивного использования и направляет ему IRP типа IRP_MJ_READ. Получив IRP, драйвер Kbdclass отмечает его как ожидающий завершения (pending), ставит в очередь и возвращает STATUS_PENDING. Потоку необработанного ввода придется ждать завершения IRP. Подключаясь к стеку, драйвер Kbdclass регистрирует у драйвера i8042prt процедуру обратного вызова KeyboardClassServiceCallback, направляя ему IRP IOCTL_INTERNAL_KEYBOARD_CONNECT. Драйвер i8042prt тоже регистрирует у системы свою процедуру обработки прерывания (ISR) I8042KeyboardInterruptService, вызовом функции IoConnectInterrupt. Когда будет нажата или отпущена клавиша, контроллер клавиатуры выработает аппаратное прерывание. Его обработчик вызовет I8042KeyboardInterruptService, которая прочитает из внутренней очереди контроллера клавиатуры необходимые данные. Т.к. обработка аппаратного прерывания происходит на повышенном IRQL, ISR делает только самую неотложную работу и ставит в очередь вызов отложенной процедуры I8042KeyboardIsrDpc (DPC). DPC работает при IRQL = DISPATCH_LEVEL. Когда IRQL понизится до DISPATCH_LEVEL, система вызовет процедуру I8042KeyboardIsrDpc, которая вызовет зарегистрированную драйвером Kbdclass процедуру обратного вызова KeyboardClassServiceCallback (также выполняется на IRQL = DISPATCH_LEVEL). KeyboardClassServiceCallback извлечет из своей очереди ожидающий завершения IRP, заполнит структуру KEYBOARD_INPUT_DATA, несущую всю необходимую информацию о нажатиях/отпусканиях клавиш, и завершит IRP. Поток необработанного ввода пробуждается, обрабатывает полученную информацию и вновь посылает IRP типа IRP_MJ_READ драйверу класса, который опять ставится в очередь до следующего нажатия/отпускания клавиши. Таким образом, у стека клавиатуры всегда есть, по крайней мере, один, ожидающий завершения IRP, и находится он в очереди драйвера Kbdclass. Стек клавиатуры представлен на рис.2.5.
Рис. 2.5. Стек клавиатуры
2.6 Kernel Streaming
Kernel streaming (KS) - это совокупность функций Windows NT 5, которые обрабатывают в режиме ядра потоковые данные, такие как аудио и видео-данные. WDM аудио-драйвер предоставляет системе свои музыкальные функции, как набор фильтров KS. Объект KS фильтра может расширить функции аудиоадаптера, если требуется дополнительная цифровая обработка аудио-потоков, которые идут через этот фильтр. Например, фильтр может преобразовывать форматы потоков, синтезировать или смешивать потоки.
Фильтр может содержать несколько пинов. Пин является точкой входа или выхода, через которую аудио-поток входит или покидает фильтр. У каждого пина есть определённый формат данных, и данные только этого формата могут проходить через пин.
Пины могут быть подсоединены к пинам других фильтров, что позволяет создавать графы фильтров. Для того чтобы быть частью графа аудио-фильтров, фильтр должен содержать не менее одного пина.
KS-фильтр - это объект ядра и к нему можно получить доступ используя HANDLE. Обращение к объекту пина производится также с использованием HANDLE. Данные входят во входные пины, проходят соответствующую обработку в узлах фильтра и выходят из выходящих пинов, как показано на рис. 2.6.
Рис.2.6. Схема аудио-фильтра
2.7 Описание формата MIDI-данных
Формат МИДИ - Musical Instrument Digital Interface. Существует 16 миди каналов (0..15). На каждом из них в одно и то же время может находиться один инструмент.
Всего существует 128 разных инструментов (0..127). Каждый инструмент занимает определенную позицию в общей структуре тембровой схемы - таблица 2.1. Каждый инструмент имеет 128 нот (0..127).
Простейшая MIDI-команда состоит из 3 байт, которые отправляются MIDI-устройству.
MIDI-команды, которые используются в данной курсовой работе:
Утановить инструмент Instrument в канале Channel
InstrumentByte[0] = 0xC0 | Channel;
InstrumentByte[1] = Instrument;
InstrumentByte[2] = 0;
Воспроизвести ноту Note в канале Channel на максимальной громкости
NoteOnByte[0] = 0x90 | Channel;
NoteOnByte[1] = Note;
NoteOnByte[2] = 0x7F;
Выключить воспроизведение ноты Note в канале Channel
NoteOffByte[0] = 0x80 | Channel;
NoteOffByte[1] = Note;
NoteOffByte[2] = 0x00;
Таблица 2.1 Инструменты MIDI
Acoustic Grand Piano
Bright acoustic piano
Electric grand piano
Honky-tonk piano
Electric piano 1
Electric piano 2
Harpsichord
Clavi
Celesta
Glockenspiel
Music box
Vibraphone
Marimba
Xylophone
Tubular bells
Dulcimer
Drawbar organ
Percussive organ
Rock organ
Church organ
Reed organ
Accordian
Harmonica
Tango accordian
Acoustic guitar (nylon)
Acoustic guitar (steel)
Jazz guitar
Clean electric guitar
Muted electric guitar
Overdrive guitar
Distortion guitar
Guitar harmonics
Accoustic bass
Fingered bass
Picked bass
Fretless bass
Slap bass 1
Slap bass 2
Synth bass 1
Synth bass 2
Violin
Viola
Cello
Contrabass
Tremolo strings
Pizzicato strings
Orchestral harp
Timpani
String ensemble 1
String ensemble 2
Synth. strings 1
Synth strings 2
Choir ahh
Choir oohh
Synth voice
Orchestral hit
Trumpet
Trombone
Tuba
Muted trumpet
French horn
Brass section
Synth brass 1
Synth brass 2
Soprano sax
Alto sax
Tenor sax
Baritone sax
Oboe
English horn
Bassoon
Clarinet
Piccolo
Flute
Recorder
Pan flute
Blown bottle
Shakuhachi
Whistle
Ocarina
Square wave
Sawtooth wave
Caliope
Chiff
Charang
Voice
Fifth's
Bass & lead
New age
Warm
Polysynth
Choir
Bowed
Metallic
Halo
Sweep
FX rain
FX soundtrack
FX crystal
FX atmosphere
FX brightness
FX goblins
FX echo drops
FX star theme
Sitar
Banjo
Shamisen
Koto
Kalimba
Bagpipe
Fiddle
Shanai
Tinkle bell
Agogo
Steel drums
Woodblock
Taiko drum
Melodic tom
Synth drum
Reverse cymbal
Guit.fret noise
Breath noise
Seashore
Bird tweet
Telephone ring
Helicopter
Applause
Gunshot
2.8 Выбор структуры программного обеспечения
Реализация проекта требует предварительного изучения уже существующих технологий, тщательного отбора методов, удовлетворяющих всем накладываемым заданием условиям. В соответствии с заданием на курсовую работу, необходимо разработать программное обеспечение, позволяющее воспроизводить музыкальные ноты с заданными параметрами при нажатии клавиш. Необходимо выбрать тип и структуру драйвера, который будет получать информацию о нажатых клавишах. Также необходимо выбрать способ доступа к аудиоустройству, способному воспроизводить MIDI-ноты.
2.8.1 Драйвер-фильтр
Из анализа архитектуры Windows XP следует, что для доступа к информации, содержащей коды нажатых или отпущенных клавиш необходимо написать драйвер. Драйвер может получить доступ к кодам нажатых или отпущенных клавиш двумя способами. Либо перехватывая IRP пакеты от других драйверов, либо самостоятельно обрабатывая прерывания от клавиатуры. Предпочтительнее выбрать драйвер-фильтр верхнего уровня, поскольку информация, возвращаемая драйвером клавиатуры, хорошо документирована и описана в литературе. Разрабатываемый драйвер должен быть WDM-драйвером.
Разрабатываемый драйвер-фильтр устанавливается над фильтром Kbdclass. Так как IRP типа IRP_MJ_READ является фактически запросом на чтение данных, то когда он идет вниз по стеку, его буфер пуст. Прочитанные данные буфер будет содержать после завершения IRP. Чтобы эти данные увидеть, фильтр должен установить в свой блок стека IRP процедуру завершения. Место драйвера-фильтра в стеке клавиатуры представлено на рис.2.7.
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9