domingo, 2 de junho de 2019

Melhorando a qualidade do som via bluetooth

Fala, pessoas!

Tenho uma caixa de som JBL Go 2 e ao conectar via Bluetooth ao meu notebook o som saía com péssima qualidade, parecendo o som transmitido via ligações telefônicas.

Identificando o problema

Para identificar o problema fui verificar a saída do comando pactl list sources:

Source #18
State: SUSPENDED
Name: bluez_sink.70_99_1C_04_9F_F0.headset_head_unit
Description: JBL GO 2
Driver: module-bluez5-device.c
Sample Specification: s16le 1ch 8000Hz
Channel Map: mono
Owner Module: 37
Mute: no
Volume: mono: 58982 /  90%
balance 0.00
Base Volume: 65536 / 100%
Monitor Source: bluez_sink.70_99_1C_04_9F_F0.headset_head_unit.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_VOLUME_CTRL LATENCY 
Properties:
bluetooth.protocol = "headset_head_unit"
device.intended_roles = "phone"
device.description = "JBL GO 2"
device.string = "70:99:1C:04:9F:F0"
device.api = "bluez"
device.class = "sound"
device.bus = "bluetooth"
device.form_factor = "speaker"
bluez.path = "/org/bluez/hci0/dev_70_99_1C_04_9F_F0"
bluez.class = "0x200414"
bluez.alias = "JBL GO 2"
device.icon_name = "audio-speakers-bluetooth"
Ports:
speaker-output: Speaker (priority: 0)
Active Port: speaker-output
Formats:
pcm

Percebi que não estava sendo utilizado o perfil a2dp_sink, mas o headset_head_unit. O Advanced Audio Distribution Profile (A2DP), segundo o Wikipedia, é um perfil que define o áudio como alta qualidade (estéreo ou mono), e torna possível sua transmissão em tempo real de um dispositivo para o outro, através de uma conexão Bluetooth. Por exemplo, músicas podem ser transferidas de um telefone celular para um fone de ouvido sem fio.

O Hands-Free Profile (HFP) e o Headset Profile (HSP) são bastante parecidos, servindo basicamente para suportar os headsets e fones de ouvido Bluetooth para serem utilizados com telefones celulares.

Para identificar os perfis disponíveis, utilizei o pactl list cards:

Card #9
Name: bluez_card.70_99_1C_04_9F_F0
Driver: module-bluez5-device.c
Owner Module: 38
Properties:
        device.description = "JBL GO 2"
        device.string = "70:99:1C:04:9F:F0"
        device.api = "bluez"
        device.class = "sound"
        device.bus = "bluetooth"
        device.form_factor = "speaker"
        bluez.path = "/org/bluez/hci0/dev_70_99_1C_04_9F_F0"
        bluez.class = "0x200414"
        bluez.alias = "JBL GO 2"
        device.icon_name = "audio-speakers-bluetooth"
Profiles:
        headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 30, available: yes)
        a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: yes)
        off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: headset_head_unit
Ports:
        speaker-output: Speaker (priority: 0, latency offset: 0 usec)
                Part of profile(s): headset_head_unit, a2dp_sink
        speaker-input: Bluetooth Input (priority: 0, latency offset: 0 usec)
                Part of profile(s): headset_head_unit

Com a lista de perfis disponíveis podemos solucionar o problema.

Solução:

No terminal, executei o comando pactl set-card-profile bluez_card.70_99_1C_04_9F_F0 a2dp_sink

Ao listar os sources novamente com pactl list sources, obtive a seguinte saída:

Source #19
State: SUSPENDED
Name: bluez_sink.70_99_1C_04_9F_F0.a2dp_sink.monitor
Description: Monitor of JBL GO 2
Driver: module-bluez5-device.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 38
Mute: no
Volume: front-left: 65536 / 100% / 0.00 dB,   front-right: 65536 / 100% / 0.00 dB
        balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor of Sink: bluez_sink.70_99_1C_04_9F_F0.a2dp_sink
Latency: 0 usec, configured 0 usec
Flags: DECIBEL_VOLUME LATENCY 
Properties:
        device.description = "Monitor of JBL GO 2"
        device.class = "monitor"
        device.string = "70:99:1C:04:9F:F0"
        device.api = "bluez"
        device.bus = "bluetooth"
        device.form_factor = "speaker"
        bluez.path = "/org/bluez/hci0/dev_70_99_1C_04_9F_F0"
        bluez.class = "0x200414"
        bluez.alias = "JBL GO 2"
        device.icon_name = "audio-speakers-bluetooth"
Formats:
        pcm

Desta forma consegui fazer com que o áudio da caixa de som bluetooth saísse com a qualidade normal.

Share:

domingo, 26 de maio de 2019

Bug dos ícones persistentes no KDE Plasma

Existe um bug no KDE Plasma (do Arch Linux, não sei se ocorre em outras distros) que faz com que o ícone do Discovery persista nos itens favoritos do Kicker (menu de aplicativos do KDE Plasma). Não importa quantas vezes façamos a sua remoção, ele sempre retorna ao iniciar a sessão.

Para resolver isso (faça por sua conta e risco):

0- Remoção do ícone dos favoritos do Kicker

Remova o ícone do Discovery normalmente, clicando com o botão direito e selecionando Remover dos favoritos.

1- Limpeza de diretório cache

Remova todos os diretórios e arquivos em cache.

rm -rf $HOME/.cache/*

2- Remoção do conteúdo do diretório kactivitymanagerd

Remova os arquivos e sub-diretórios do kactivitymanagerd

rm -rf $HOME/.local/share/kactivitymanagerd/*

3- Reconstrução do cache do KService

Utilize o kbuildsycoca5

kbuildsycoca5 --noincremental

Por fim, reinicie sua sessão desktop.

O problema com os ícones persistentes não irá ocorrer mais.

Share:

Monitorar diretório e converter arquivos automaticamente

Costumo elaborar minhas postagens em markdown e em seguida convertê-las para html.

Para automatizar o processo necessitamos de três ferramentas:

- pandoc

- notify-send

- inotify-tools

Com os pacotes instalados, utilizaremos o seguinte script para Bash:

#!/usr/bin/env bash

WORKDIR=${HOME}/Publicacoes

inotifywait -q -m -e create $WORKDIR | \
    while read i; do
        FILE=$(echo $i | grep .md  | sed 's/^.*CREATE //g')
        cd $WORKDIR

        if pandoc "$FILE" -o "$(echo $FILE | sed 's/\.md/.html/g')" 2> /dev/null ; then
            notify-send -u low "$(printf "Arquivo $FILE convertido para html")"
        fi
    done

Entendendo o comando inotifywait:

-q

Menos verbosidade (menos informações na saída padrão)

-m

Modo monitoramento habilitado (não sai do inotifywait na primeira ocorrência)

-e create:

Monitora os eventos CREATE (criação de arquivos) dentro do diretório informado

Como utilizar o script?

1. Crie um diretório (Ex. Publicacoes) dentro da pasta pessoal de seu usuário:

mkdir $HOME/Publicacoes

2. Salve o script com permissões de execução e configure seu ambiente desktop para iniciá-lo automaticamente

No KDE, basta colocar o script dentro do diretório $HOME/.config/autostart-scripts/.

3. Reinicie a sessão de seu usuário (logoff, login)

Pronto.

Basta copiar os arquivos com a extensão .md para o diretório e os mesmos serão convertidos para .html.

Com o notify-send você receberá notificações no seu ambiente desktop após cada conversão.

Share:

Gerador de número randômico em C++ e Python 3

Realizando mais alguns testes, criei um gerador de números randomicos, no qual o usuário informa um número inteiro e o programa utiliza esse número como escopo para gerar um número randômico.

A saída com o comando time foi conforme pode ser visto abaixo:

Escrito em C++:

$ time ./randomizer_c 1000000

Welcome to random int.
The number you typed as maximum in a range was 1000000

The random number is 2043

real    0m0.006s
user    0m0.006s
sys     0m0.000s

Escrito em Python 3:

$ time python3 -c "import random2 ; a = random2.randint(0,1000000) ; print('O numero sorteado foi {}'.format(a))"

O numero sorteado foi 940853

real    0m0.052s
user    0m0.046s
sys     0m0.007s

O código do “random int” em C++:

#include <iostream> // For cout and cin
#include <cstdlib> // For srand() and rand()
#include <ctime> // For time()
#include <cstring> // For strtol()

// randomizer code as seen on http://www.fredosaurus.com/notes-cpp/misc/random.html

using namespace std;

int number;
int randomizer(int number);

int main(int argc, char*argv[]) {

    char*p;
    int randomized;

    if(!argv[1]) {

        cout << "Welcome to random int.\nTo randomize a number between 1 and 20, type 20, for example." << endl;
        cout << "Please, type an integer number: " << endl;
        cin >> number;
        randomized = randomizer(number);
        cout << "\nThe random number is " << randomized << endl;

    } else {

        int number = strtol(argv[1], &p, 10); // https://stackoverflow.com/questions/9748393/how-can-i-get-argv-as-int/38669018

        cout << "Welcome to random int.\nThe number you typed as maximum in a range was " << argv[1] << endl;
        randomized = randomizer(number);
        cout << "\nThe random number is " << randomized << endl;

    }

    return 0;
}

int randomizer(int number) {

    int random;

    srand(time(0)); // initializa random number generator.
    random = (rand() % number) + 1;

    return random;
}
Share:

terça-feira, 4 de setembro de 2018

Visualizar e alterar o cabeçalho de um arquivo

Olá, mundo.

Alguém já teve o desprazer de fazer o download de uma arquivo PDF e não conseguir exibi-lo no visualizador padrão?

Isso já aconteceu comigo algumas vezes, mas hoje precisei abrir um documento neste formato digital e simplesmente apareceu: NADA. A tela fica toda preta dentro do visualizador de PDF. Utilizo o Zathura, software que lhe permite escolher qual biblioteca será utilizada como backend para visualizar os PDFs (optei pela mais utilizada - poppler) e é altamente customizável através de plugins, entre outros recursos.

Daí veio a idéia de debugar através do terminal. Executei o comando com o nome do arquivo:

zathura arquivo.pdf

Eis que apareceu o erro error: Unknown file type: 'application/octet-stream', o que me permitiu identificar que o cabeçalho do arquivo não estava dentro do padrão PDF.

Com a ferramenta hexdump consegui visualizar os bytes não deveriam preceder o %PDF1.4.

hexdump -C arquivo.pdf | more

00000000  0d 0a 0d 0a 0d 0a 0d 0a  0d 0a 0d 0a 0d 0a 0d 0a  |................|
*
00000030  0d 0a 0d 0a 25 50 44 46  2d 31 2e 34 0a 25 e2 e3  |....%PDF-1.4.%..|
00000040  cf d3 0a 32 20 30 20 6f  62 6a 0a 3c 3c 2f 4c 65  |...2 0 obj.<</Le|
00000050  6e 67 74 68 20 34 38 37  39 2f 46 69 6c 74 65 72  |ngth 4879/Filter|
00000060  2f 46 6c 61 74 65 44 65  63 6f 64 65 3e 3e 73 74  |/FlateDecode>>st|
00000070  72 65 61 6d 0a 78 da a5  5a 0b 98 15 c5 95 ae d3  |ream.x..Z.......|

Daí, resolvi abrir o arquivo pelo VIM e ele apareceu assim:

^M
^M
^M
^M
%PDF-1.4
%âãÏÓ
2 0 obj
<</Length 4879/Filter/FlateDecode>>stream

Foram 26 linhas com o caractere ^M. Deletei essas linhas e salvei o arquivo.

Problema resolvido.

Após essa alteração a saída do comando hexdump -C arquivo.pdf passou a exibir a primeira linha assim:

00000000  25 50 44 46 2d 31 2e 34  0a 25 e2 e3 cf d3 0a 32  |%PDF-1.4.%.....2|

e o arquivo pôde ser aberto normalmente.

Share:

sexta-feira, 15 de junho de 2018

Converter manual (man) para PDF no Linux

Beleza, galera?

Dica rápida: Como converter qualquer manual (man) para PDF no Linux.

1. Abra o terminal

2. Execute o comando

man -t <nome_do_app> | ps2pdf - <arquivo_de_saida.pdf>

Por exemplo:

man -t bash | ps2pdf - manual_bash.pdf

Entendendo os comandos:

man -t: Executa o man e formata a saída com o groff.

bash: Nome do software que queremos o manual.

ps2pdf -: Faz a conversão da saída - formatada pelo groff. O símbolo - representa stdout (saída padrão).

manual_bash.pdf: Nome do arquivo que será gerado.

Um abraço e ffffffffffffffalou!
Share:

quarta-feira, 6 de junho de 2018

Debian 9 + Openbox

A insônia pode ser considerada aceitável quando é produtiva.

Eis que instalei o Debian minimal, lembrei dos velhos tempos de Openbox + tint2 + conky + compton + parcellite + feh + dmenu + scrot + dunst + algumas ferramentas do xfce, scripts...

Alterei alguns temas do conky e do tint2, fiz o wallpaper de forma simples no GIMP, baseado nas cores do Debian.







... falta algumas coisas.


Share: