1 ноября 2011, 16:53
GStreamer audio plugin для QNX
В процессе портирования WebKit в нашем проекте мне пришлось написать аудио плагин для GStreamer, который позволяет выводить звук в этом мультимедийном framework’е на qnx . На текущий момент мне известен только один выход для пользователей qnx — это использовать SDL gst plugin. Хотя как по мне — это совсем не элегантное решение тащить огромную библиотеку за собой ради простого вывода звука.
Поскольку в основу моего плагина лёг другой open source плагин (от него правда осталось не более 5% кода), то я в скором времени выложу исходники своего плагина на github, естественно предварительно убрав все проектно специфичные куски кода. Надеюсь моя работа будет кому-то полезна.
Поскольку в основу моего плагина лёг другой open source плагин (от него правда осталось не более 5% кода), то я в скором времени выложу исходники своего плагина на github, естественно предварительно убрав все проектно специфичные куски кода. Надеюсь моя работа будет кому-то полезна.
нет комментариев
26 сентября 2011, 12:01
Rapoo E9080: Обзор очень компактной клавиатуры с тачпадом.

Я не любитель писания обзоров железа, но поскольку я стал обладателем клавиатуры заслуживающей внимания, то посчитал, что надо поделится.
Задался я как-то поиском компактной беспроводной клавиатуры для своего HTPC и зашедши на ebay я нашёл прекрасную клавиатуру такую, какую я очень хотел. Rapoo не очень известный у нас китайский производитель, но забегая вперёд скажу, что я не в первый раз покупаю их продукты, и я постоянно доволен качеством их продуктов не смотря на репутацию китайских производителей. В данном случае — производитель серьёзно подходит к качеству своей продукции. Держать клавиатуру в руках приятно и чувствуется качество сборки.
Основные характеристики
Частота: 2.4GHz
OS: Windows XP, Windows 7, Mac OS X (мак ось я сам проверял,
Толщина: 5.6мм
Радиус: 10м
Приёмник: nano
Цена: ~50$
Комплектация
Клавиатура, нано приёмник, 2 батарейки ААА и документация.
Толщина
Толщина у клавиатуры действительно очень маленькая, всего 5.6мм, что сродни маковским алюминиевым клавиатурам.


Клавиатура
Пластик клавиш шершавый и очень приятный на ощупь. Дополнительные клавиши доступны через кнопку Fn. Скажу сразу: Fn расположена там где ей и место — между Ctrl и Win, что будет оценено почти всеми пользователями.
Ход у клавиш при такой толщине корпуса, конечно же короткий, ноутбучный. Тут никаких нареканий — приятно и комфортно работать (я вообще любитель короткого хода, так что это субъективно).
Дополнительные клавиши стандартные — это навигация в браузере, медиа плеер и громкость. Стоит отметить, что на клавиатуре так же присутствует Insert, который любят иногда выкидывать.


Тачпад
Тачпад выполнен из точно такого же пластика как и клавиши, что совсем не пошло ему на пользу — скользить пальцами по нему менее удобно чем, к примеру, на том же макбуке, где тачпад гладкий. Поэтому создаётся впечатление, что тачпад немного сопротивляется скольжению.

Как можно заметить, на самом тачпаде нанесены символы дополнительной цифровой клавиатуры. Переключение между тачпадом и клавиатурой осуществляется слайдовым движением аля «айфон анлок» по надписи «SLIDE HERE». После чего возле слайдера 3-4 раза мигнёт светодиод сообщающий о переключении. Никакой другой индикации на клавиатуре нет. Если вы забыли в каком режиме вы оставили клавиатуру, в тачпаде или в режиме клавиатуры, вспоминать прийдётся только экспериментальным путём.
Тачпад распознаёт следующие жесты:
Один палец — управление движением курсора мышки.
Два раза стукнуть пальцем — щелчёк левой кнопкой мышки.
Касание тремя пальцами — щелчёк правой кнопкой мышки (слегка не удобно).
Два пальца — скроллирование (я смог заставить работать только вертикальную прокрутку).
Обратите внимание: распознование жестов и касаний несколькими пальцами реализовано ПО встроенным в клавиатуру!
Поскольку никаких дисков и утилит в поставке не шло, то и настраивать тачпад можно только стандартными утилитами операционной системы. А настраивать многим вероятно прийдётся,
Ресивер
Тут сказать особо нечего — стандартный нано-ресивер.

Обратная сторона
Обратная сторона клавиатуры выполненна из металла на котором очень аккуратно выгравированы логотип производителя и значки соответствия стандартам. Металл очень маркий и следы на нём остаются мгновенно, а оттираются достаточно сложно. Сам металл выглядит очень солидно за счёт аккуратной и не броской текстуры.

Батарейный отсек
Батареи используются формата AAA (маленький «пальчик»). Как было сказано в начале — батарейки входят в комплект поставки.
Рядом с батарейным отсеком есть место для ресивера. Там же рядом располагается переключатель включения питания. Больше никаких других кнопок и рычажков нету (например сброс или соединение как в клавиатурах Logitech).

В интерьере


Впечатления
Впечатления как я уже говорил — положительные. Единственный небольшой минус — это не слишком скользкая поверхность тачпада. По большому счёту недостатоков у клавиатуры нет, но вот использовать её с тачпадом как полноценный рабочий инструмент 8 часов в день, без мышки — будет сложновато, это всё же не эппловский тачпад с широким функционалом. Но вот как дополнительная клавиатура (для HTPC как в моём случае) она в самый раз.
Rapoo это один из тех немногих самодостаточных китайских производителей, которые заботятся о качестве своей продукции без какого либо постороннего контроля западных менеджеров. Держа в руках эту клавиатуру чувствуется, что она сделана добротно: никаких люфтов, разболтанностей и качественные материалы. Однако на 25 сентября, на сайте производителя по каким-то причинам попасть на страницу с этим продуктом нет возможности, хотя на главной большой рекламный баннер имеется.
Предугадывая возможный вопрос: статистикой по долговечности работы от батареек я не обладаю,
Добавлено месяц спустя
После месяца использования клавиатуры, могу сказать, что она просто нормальная. Не плохая, не отличная, а нормальная. Я разбалован тачпадами Apple, вот они — отличные. Я же эту клавиатуру использую только с FullHD телевизором и лично мне не хватает быстроты курсора — двигать курсор в разные части экрана приходится за несколько касаний,
В качестве основного рабочего инструмента (если вы работаете за клавиатурой 6-8 часов) — использовать не советую: я подозреваю, что досадные мелочи с тачпадом тут же превратятся в серьёзные недостатки и будут портить нервы. [Добавлено ещё через пару недель: довелось поработать целый день с клавиатурой переустанавливая систему. Использовать её всё же очень сложно из-за огромного количества ложных срабатываний тачпада — руки попадая в ту часть клавиатуры (курсорные клавиши, клавиша Enter) часто цепляют тачпад и курсор мыши на экране начинает творить мелкие пакости которые изрядно раздражают.]
К клавиатуре вопросов нет, но замена мышки сенсорной панелью в этом случае не пройдёт. Дизайнерам и художникам этот продукт я совершенно не рекомендую. Даже на эппловских тачпадах работать в графических редакторах очень сложно (проверено лично), а с этим тачпадом можно вообще загреметь в больницу с расшатанной психикой и нервными срывами. Он попросту не проектировался для такого. Так к примеру тут нет возможности «перехватывать» объекты. Перехватом я называю момент, когда надо перетащить объект на большое расстояние (файл к примеру), но дотащив «объект» до края тача дальше двигаться не можешь, тогда ставишь второй палец в начало тача и продолжаешь тянуть дальше — именно так реализовано в тачах от Apple. Тут, увы, такого нет и в помине. Тут реализован очень и очень простой тач (Apple не зря покрыла патентами свои разработки в области сенсорных технологий). Да и Windows совсем не touch ориентированная система в отличие от Mac OS X, в которой без тача уже сложновато. Это тоже играет свою роль в удобстве использования.
Есть ещё один неудобный момент. Если клавиатуру не использовать 1-2 минуты, то она впадает в режим сна с пониженным энергопотреблением, тачпад перестаёт функционировать и не реагирует на касания, пока любая из клавиш не будет нажата. Таким образом, к примеру, вывести компьютер из режима энергосбережения просто касанием к тачпаду (по аналогии с мышкой) — нельзя. Но я для себя уже приловчился выводить клавиатуру из сна нажатием кнопки Fn — это самая безопасная кнопка и не произойдёт ненужных действий.
Как итог тачпад отлично выполняет основные функции: движение мышкой, перетаскивание объектов, скроллинг и вызов контекстного меню. Но всё это прекрасно, ровно до того момента, пока не требуется действие упирающееся в края тачпада: двигать курсором по большим экранам и перетаскивать объекты на дальние расстояния. Таким образом этот тач удобен пока ваше действие происходит на экране в небольших пределах.
23 августа 2011, 18:40
Как определить, что клиент закрыл соединение
Мне тут на днях потребовалось в клиент-серверном коде моментально определить, закрыл ли клиент соединение или оно всё ещё держится. Решение требовалось сделать как на .NET так и на POSIX с помощью обычного C. Быстрый анализ различных документаций показал, что решения «в лоб» в виде вызова некоторой функции аля «getConnectionState(soket)» просто не существует ни в posix, ни в .NET.
Самое интересное, что по спецификации TCP этот протокол позволяет вполне точно определить когда клиент отсоединился. Речь конечно идёт о корректном завершении соединения, а не о физическом обрыве связи которое нельзя определить штатными средствами tcp протокола.
Требование к задаче следующее:т. к. в разные моменты времени в зависимости от контекста она сигнализирует о совершенно разных событиях в сокете/дискрипторе.
В нашем частном случае после того как соединение было успешно установлено, poll() возвращает true/non zero если сокет имеет данные, либо соединение разорвано (наша задача затем определить что именно произошло: пришли данные или соединение закрыто). В противном случае по таймауту возвращает false/zero (т. е. за время таймаута событий в сокете не случилось). Если к примеру сокет находится только в состоянии установки соединения, то результат возвращённый poll() будет указывать на другие события связанные с сокетом. Это стоит помнить.
Теперь код.
C#:
С/С++:
Приведенный выше код прекрасно отрабатывает и мгновенно отлавливает ситуации когда клиент закрывает соединение.
Ну и в заключение хочется сказать, что данные куски кода были написаны для внутренних тестирующих утилит и посему к ним никаких сверх требований не предъявлялось, как следствие вероятно их можно даже оптимизировать.
Happy coding! =)
Самое интересное, что по спецификации TCP этот протокол позволяет вполне точно определить когда клиент отсоединился. Речь конечно идёт о корректном завершении соединения, а не о физическом обрыве связи которое нельзя определить штатными средствами tcp протокола.
Требование к задаче следующее:
- Должна быть функция которая гарантированно получает N байт из сокета.
- Функция должна без промедлений определять отвалившегося клиента.
- .NET C# версия должна выбрасывать свой ConnectionLostException в случае разрыва соединения.
- POSIX C/C++ версия должна возвращать количество полученных байт или ноль в случае разрыва соединения.
В нашем частном случае после того как соединение было успешно установлено, poll() возвращает true/non zero если сокет имеет данные, либо соединение разорвано (наша задача затем определить что именно произошло: пришли данные или соединение закрыто). В противном случае по таймауту возвращает false/zero (
Теперь код.
C#:
- static public void ReceiveBytes(Socket sock, byte[] data)
- {
- int totalReceived = 0;
- int size = data.Length;
- // Цикл до тех пор пока не получим все данные
- while (totalReceived < size)
- {
- // Ждём 0.1 секунду события: или новые данные или обрыв
- if (sock.Poll(100000, SelectMode.SelectRead))
- {
- // Проверяем есть ли какие-то данные у сокета для нас
- if (sock.Available == 0)
- {
- // Данных нет, но раз Poll() вернул true — это обрыв
- // поэтому бросаем свой ConnectionLostException
- throw new ConnectionLostException();
- }
- try
- {
- // Получаем данные
- totalReceived += sock.Receive(data, totalReceived /* offset */,
- size - totalReceived /* size to recieve */,
- SocketFlags.None);
- }
- catch (SocketException ex)
- {
- // В зависимости от того как сконфигурирован сокет
- // мы можем поймать таймаут или попытку заблокировать сокет
- if (ex.SocketErrorCode == SocketError.TimedOut ||
- ex.SocketErrorCode == SocketError.WouldBlock)
- {
- // Это не критично и мы продолжаем цикл
- continue;
- }
- else
- {
- // Остальные исключения говорят о какой-то ошибке
- break;
- }
- }
- }
- }
- }
С/С++:
- int recieveData(int socket, void * buffer, int size)
- {
- int totalRecieved = 0, arrived = 0;
- struct pollfd pfd;
- // Подготавливаем структуру для вызова функции poll()
- pfd.fd = socket; // Указываем дискриптор сокета который интересует
- pfd.events = POLLIN | POLLHUP | POLLRDNORM;
- // Цикл пока не получим все данные
- while(totalRecieved < size)
- {
- // Ожидаем событие в сокете с таймаутом 100 миллисекунд
- if(poll(&pfd, 1, 100) > 0)
- {
- // Произошло какое-то событие — пытаемся получить данные
- arrived = recv(socket, (char*)buffer + totalRecieved, size - totalRecieved, MSG_DONTWAIT);
- // Если данных не пришло после того как poll() вернул не нулевой
- // результат — это означает только обрыв соединения
- if(arrived == -1 || totalRecieved == arrived)
- {
- // Сбрасываем счётчик полученных данных, что скажет об разрыве соединения
- totalRecieved = 0;
- break;
- }
- // Продолжаем получать данные
- totalRecieved += arrived;
- }
- }
- return totalRecieved;
- }
Приведенный выше код прекрасно отрабатывает и мгновенно отлавливает ситуации когда клиент закрывает соединение.
Ну и в заключение хочется сказать, что данные куски кода были написаны для внутренних тестирующих утилит и посему к ним никаких сверх требований не предъявлялось, как следствие вероятно их можно даже оптимизировать.
Happy coding! =)
2 августа 2011, 16:58
Aperture 3 и линейный DNG
Вполне вероятно, что если бы в мире не было проблем, то и писать было бы не о чем. =) В общем есть у Apple Aperture 3 два недостатка, которые омрачили мне впечатление от программы. Первый — программа из рук вон плохо поддерживает поиск на русском языке (Вася ≠ вася), а с нечётким поиском совсем худо. Второй недостаток многие вероятно никогда даже и не заметят, уж очень он специфический. Проявляется он только в связке Aperture 3 + DNG + (плёночный) сканер. Однажды домой ко мне попал плёночный сканер с помощью которого я отсканировал несколько цветных плёнок. Результат работы вышел на многие гигабайты, т. к. софт сканера умел сохранять 16-битные сканы только в TIFF. Чтобы хоть как-то вернуть украденное таким расточительством место — решил перегнать tiff в dng. Само конвертирование не заняло много времени, а вот попытка загрузить получившиеся dng файлы в Aperture 3 неожиданно провалилась. Aperture упорно ругалась на то, что «извините, но линейные DNG мы не кушаем». Это что ещё такое?
Сходил на сайт технической поддержки Apple — не помогло. Интернеты так же молчали. В итоге после нескольких экспериментов я всё же пришёл к выводу в чём загвоздка.
Aperture прекрасно открывает dng файлы полученные из raw фотографий с цифровых фотокамер и напрочь отказывается от dng созданных после сканирования. Значит разница в том, как хранятся пиксели внутри dng. Тут я вспомнил о том, что у цифровых камер RGB пиксели матрицы располагаются особым образом (фильтр Байера):

Этот формат используется большинством камер (кроме Sigma c их X3 Foveon матрицами и некоторыми Fuji на сколько мне известно). А сканер в силу иной природы получения картинки создаёт линейную картинку:

Сама спецификация dng определяет, что внутри dng файла картинка может быть сохранена в любом из этих форматов, а вот купертиновцы похоже подумали «99% камер использует формат пекселов на основе Байера. Если кто-то и конвертирует в формат DNG, то только из raw формата камер. Так зачем какие-то редкие линейные форматы поддерживать в dng?» и отбросили поддержку. Другого объяснения для себя не нашёл. С одной стороны — они съэкономили время на разработке, а с другой сделали кривую поддержку открытой спецификации.
По итогу окончательного решения нет. Если вам довелось с этим столкнуться — ищите обходные пути: используйте другой формат или другую программу. Если не принципиально — используйте Adobe Lightroom, там поддержка dng отличная. Если принципиально, то можете сохранить не в dng, а в psd — он более менее нормально поддерживается Aperture.
Happy using! =)
Сходил на сайт технической поддержки Apple — не помогло. Интернеты так же молчали. В итоге после нескольких экспериментов я всё же пришёл к выводу в чём загвоздка.
Aperture прекрасно открывает dng файлы полученные из raw фотографий с цифровых фотокамер и напрочь отказывается от dng созданных после сканирования. Значит разница в том, как хранятся пиксели внутри dng. Тут я вспомнил о том, что у цифровых камер RGB пиксели матрицы располагаются особым образом (фильтр Байера):

Этот формат используется большинством камер (кроме Sigma c их X3 Foveon матрицами и некоторыми Fuji на сколько мне известно). А сканер в силу иной природы получения картинки создаёт линейную картинку:

Сама спецификация dng определяет, что внутри dng файла картинка может быть сохранена в любом из этих форматов, а вот купертиновцы похоже подумали «99% камер использует формат пекселов на основе Байера. Если кто-то и конвертирует в формат DNG, то только из raw формата камер. Так зачем какие-то редкие линейные форматы поддерживать в dng?» и отбросили поддержку. Другого объяснения для себя не нашёл. С одной стороны — они съэкономили время на разработке, а с другой сделали кривую поддержку открытой спецификации.
По итогу окончательного решения нет. Если вам довелось с этим столкнуться — ищите обходные пути: используйте другой формат или другую программу. Если не принципиально — используйте Adobe Lightroom, там поддержка dng отличная. Если принципиально, то можете сохранить не в dng, а в psd — он более менее нормально поддерживается Aperture.
Happy using! =)
17 июля 2011, 18:08
Возможно самое короткое преобразование в bool
В нашем текущем проекте мы портируем WebKit под проект заказчика и приходится крайне много копаться в эппловском WebKit’е и немного в гуглевском Chromiume. Сколько бы я не занимался C++ , я постоянно нахожу что-то интересное. Поскольку chromium пишут достаточно серьёзные спецы, то я периодически наталкиваюсь на занимательные (на мой взгляд) куски кода на которых можно поучиться.
Так например совсем недавно я увидел выражение вида:
return !!count;
В первую секунду было удивление, а в следующую секунду стало понятно, что эта запись преобразует любое числовое значение к bool. Очень лаконично и красиво как по мне, вместо привычного:
return (bool)count;
В принципе такое преобразование должно так же работать в java, c#, да и наверное во всех производных от С языках.
Happy coding! =)
Так например совсем недавно я увидел выражение вида:
return !!count;
В первую секунду было удивление, а в следующую секунду стало понятно, что эта запись преобразует любое числовое значение к bool. Очень лаконично и красиво как по мне, вместо привычного:
return (bool)count;
В принципе такое преобразование должно так же работать в java, c#, да и наверное во всех производных от С языках.
Happy coding! =)
| Заметки | ← | следующие | Ctrl | предыдущие | → |
