- PVSM.RU - https://www.pvsm.ru -
К сожалению, довелось мне простудиться, застрять дома на три дня, и от безудержного веселья начать перебирать «долгий ящик». В оном ящике я обнаружил «usb уведомитель» от фирмы CBR. Девайс предназначен, для оповещения о входящих сообщений на email, посредством изменения цветовой гаммы.
Не знаю, повезло мне, или наоборот, но девайс отказался исполнять свои непосредственные функции. Он определился как HID совместимое устройство, однако чудо-софт работать не захотел.
Сначала я подумал о написании софта, который бы повторял заявленный функционал, но основательно подумав, понял, что «уведомитель» мне нужен как собаке пятая нога. С другой стороны внешний вид светодиода в капельке мне приглянулся и я решил сделать из устройства обыкновенный ночник-подсветку.
Для начала необходимо было узнать какие же байты отвечают за смену цвета (не забываем это же все-таки HID). Никакой внятной документации не нашлось и пришлось действовать эмпирическим путем (научный метод «пальцем в небо»). Для таких изысканий есть замечательный софт SimpleHIDWrite [1]. Я думал, что на подбор команд у меня уйдет приличное время, однако все оказалось очень просто. Ставим ReportID 00, отправляем 01 00 00 00 00 и наш чудо-девайс окрашивается в красный цвет. Список остальных управляющих байтов на смену цвета приведен ниже:
Отлично, теперь осталось дело за малым, написать небольшую оболочку для управления устройством. Так как никакого GUI не предвидеться, решил сделать управление девайсом в виде windows службы на c#. Реализация обмена данными между хостом и HID-устройством с использованием HidLibrary [2] выглядит следующим образом:
// vendor id, является неизменным, можно узнать из диспетчера устройств в свойствах.
private int vid = 0x1294;
//получаем список устройства с указанным vid'ом
var devs = HidDevices.Enumerate(vid).ToList();
//выбираем устройство, num_devices. параметр из .config
var dev = devs[device_num];
if(dev != null)
{
//создаем масиив с управляющими байтами
var data = new byte[5];
//в obj находится байт для смены цвета
data[0] = (byte)(int)obj;
//создаем Report, т.е. хост отдает команду HID_SET_REPORT
var report = dev.CreateReport();
//подготавливаем Report
report.Data = data;
//и отправляем
dev.WriteReport(report);
}
Теперь необходимо определиться как и когда менять цвет, сначала хотел реализовать по таймеру, но это показалось скучным, поэтому решил сделать смену цвета по уровню звука с аудио-входа (подразумевается, что есть микрофон или вебка с микрофоном). Для этого использовал NAudio [3]. Как управляться с данной библиотекой расписано здесь [4], я лишь приведу обработчик, который отвечает за определение пика уровня звука. В принципе код позаимствован в большей части из статьи по ссылке.
//инициализируем аудио-вход 0, с частотой 8000 Гц и моно-каналом
var dev = new WaveIn(WaveCallbackInfo.FunctionCallback());
dev.DeviceNumber = 0;
//подписываемся на событие обработки данных с аудио-входа
dev.DataAvailable += dev_DataAvailable;
dev.WaveFormat = new WaveFormat(8000, 1);
dev.StartRecording();
void dev_DataAvailable(object sender, WaveInEventArgs e)
{
//получаем максимальный пик из входящего буффера
var max = getValueMax(e.Buffer, e.BytesRecorded);
//если больше заданного уровня
if(max > _trigger)
{
if(ChangeLevelVolumeMax != null)
{
//инициализируем событие, на смену цвета
ChangeLevelVolumeMax(this, e);
}
}
}
private float getValueMax(byte[] buffer, int lenght)
{
//массив уровней
List<float> l_sample32 = new List<float>();
//определяем уровень, между двумя соседствующими значениями
for (int index = 0; index < lenght; index += 2)
{
float sample32 = (float)(short)((buffer[index + 1] << 8) |
buffer[index + 0]) / 32768f;
l_sample32.Add(sample32);
}
//выбираем максимальный
var max = l_sample32.Max();
return max;
}
Ну и выше приведенный код упаковываем в оболочку windows службы [5]:
protected override void OnStart(string[] args)
{
//USB Notifier
device = new cApi(cSettings.Usb);
//Audio
audio = new cAudio(cSettings.Audio,
cSettings.Rate,
cSettings.Chanel,
cSettings.Trigger);
audio.ChangeLevelVolumeMax += audio_ChangeLevelVolumeMax;
base.OnStart(args);
}
void audio_ChangeLevelVolumeMax(object sender, NAudio.Wave.WaveInEventArgs e)
{
//смена цвета
device.setNextColor();
}
protected override void OnStop()
{
device.Off();
device.Dispose();
audio.Dispose();
base.OnStop();
}
Дальше осталось создать развертывание службы с помощью Wix. За подробностями пожалуйте на гит [6]. Ну и напоследок видео:
Автор: ScorpoNya
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/diy/67095
Ссылки в тексте:
[1] SimpleHIDWrite: http://janaxelson.com/hidpage.htm#tools
[2] HidLibrary: https://github.com/mikeobrien/HidLibrary
[3] NAudio: http://naudio.codeplex.com/
[4] здесь : http://channel9.msdn.com/coding4fun/articles/NET-Voice-Recorder
[5] windows службы: http://habrahabr.ru/post/102826/
[6] гит: https://github.com/dmtmalin/cbr_ug003
[7] Источник: http://habrahabr.ru/post/232729/
Нажмите здесь для печати.