Saturday, January 25, 2014

Xmonad - Random Background at Interval

Make a file randombackgroundatinterval:

#!/bin/bash
while x=0;do find $1 | grep 'jpg\|png' | shuf | head -n 1 | xargs -i xloadimage -border black -onroot -fullscreen '{}'; sleep $2; done

run it with the top directory for images and how often you want them to change.

example:
./randombackgroundatinterval /home/<YOUR USER NAME>/Pictures 3

Would pick a random jpg or png from the /home/<YOUR USER NAME>/Pictures directory, and its subs and display a new one every three seconds.


Tuesday, January 7, 2014

Music


Current script for starting Music

#!/bin/bash
echo "Spawning jackd -d alsa"
jackd -d alsa &
echo "Waiting For Jack to Wake Up...."
sleep 3
echo "Spawning a2jmidid -e"
a2jmidid -e &
sleep 3
echo "Spawning qjacktl"
qjackctl &
echo "Spawning qsynth"
qsynth &
echo "Finished"

Current script for Starting Midi listener

#!/usr/sbin/python2.7
from bottle import run, route, request
import alsaseq     
from time import sleep

alsaseq.client('WebMIDI', 1,1, False)#http://127.0.0.1/midi?note=60&duration=100
alsaseq.connectfrom(0,129,0)
IP = "127.0.0.1"
VOICE = 127
PLAYBACK_RATE = .5

notes = []

def save_note(note, duration, channel):
    notes.append({"note":note,"duration":duration,"channel":channel})

def play_note(note, duration, channel):   
    alsaseq.output( (6, 1, 0, 1, (5, 0), (0, 0), (0, 0), (channel,
int(note), 127, 0, int(duration))) )

def playback():
    for note in notes:
        sleep(PLAYBACK_RATE)
        play_note(note["note"],note["duration"],note["channel"])

@route('/midiclear',method="GET")
def midiclear():
    notes[:] = []

@route('/midiplayback',method="GET")
def midiplayback():
    playback()

@route('/midi',method="GET")
def midi():
        note = int(request.query['note'])
        duration = int(request.query['duration'])
        channel = int(request.query['channel'])
        save_note(note, duration, channel)
        play_note(note, duration, channel)
        return {"data":{"note":note,"duration":duration,"status":alsaseq.status()}}

run(host=IP, port=8080)


Current html page:
<html>
<head>
    <script src="js/jquery-1.9.1.js"></script>
    <script src="js/jquery-ui-1.10.3.custom.js"></script>
    <link href="css/sunny/jquery-ui-1.10.3.custom.css" rel="stylesheet">
    <meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=no'>
    <script type="text/javascript" src="midi.js"></script>
    <style>
        div.normal,div.upper,div.lower,#playback,#clear,#channel,#channel_up,#channel_down {height:60px;width:80px;position:
fixed;
text-align: center;
vertical-align:middle;
display: table-cell;}

        div.lower {background-color:blue}
        div.upper {background-color:green}
        div.bnote {background-color:black; color:white}

        div.pinky.lower {top:140px}
        div.pinky.normal {top:80px}
        div.pinky.upper {top:20px}

        div.ring.lower, div.middle.lower {top:120px}
        div.ring.normal, div.middle.normal {top:60px}
        div.ring.upper , div.middle.upper  {top:0px}

        div.pointer.lower {top:130px}
        div.pointer.normal {top:70px}
        div.pointer.upper  {top:10px}

        div.thumb.lower {top:420px}
        div.thumb.normal {top:360px}
        div.thumb.upper  {top:300px}

        div.b  {left:900px}
        div.as {left:800px}
        div.a {left:700px}
        div.gs {left:600px}
        div.g {left:620px}
        div.fs {left:520px}
        div.e {left:300px}
        div.f {left:400px}
        div.ds {left:300px}
        div.d {left:200px}
        div.cs {left:100px}
        div.c {left:0px}
       
        #playback{background-color:red;color:white;bottom:20px;left:20px;}
        #clear{background-color:green;color:yellow;bottom:20px;right:20px;}

       
        #channel{background-color:green;color:yellow;bottom:20px;right:400px;}
        #channel_up{background-color:green;color:yellow;bottom:20px;right:300px;}
        #channel_down{background-color:green;color:yellow;bottom:20px;right:500px;}
    </style>
</head>
<body>

        <div class='lower pinky c' id='c3' ></div>
        <div class='normal pinky c' id='c4' ><p>C</p></div>
        <div class='upper pinky c' id='c5' ></div>

        <div class='lower ring cs' id='cs3' ></div>
        <div class='normal ring cs bnote' id='cs4' ><p>C#</p></div>
        <div class='upper ring cs' id='cs5' ></div>   

        <div class='lower middle d' id='d3' ></div>
        <div class='normal middle d' id='d4' ><p>D</p></div>
        <div class='upper middle d' id='d5' ></div>   

        <div class='lower pointer ds' id='ds3' ></div>
        <div class='normal pointer ds bnote' id='ds4' ><p>D#</p></div>
        <div class='upper pointer ds' id='ds5' ></div>   

        <div class='lower thumb e' id='e3' ></div>
        <div class='normal thumb e' id='e4' ><p>E</p></div>
        <div class='upper thumb e' id='e5' ></div>   

        <div class='lower thumb f' id='f3' ></div>
        <div class='normal thumb f' id='f4' ><p>F</p></div>
        <div class='upper thumb f' id='f5' ></div>   

        <div class='lower thumb fs' id='fs3' ></div>
        <div class='normal thumb fs bnote' id='fs4' ><p>F#</p></div>
        <div class='upper thumb fs' id='fs5' ></div>   

        <div class='lower thumb g' id='g3' ></div>
        <div class='normal thumb g' id='g4' ><p>G</p></div>
        <div class='upper thumb g' id='g5' ></div>   

        <div class='lower pointer gs' id='gs3' ></div>
        <div class='normal pointer gs bnote' id='gs4' ><p>G#</p></div>
        <div class='upper pointer gs' id='gs5' ></div>   

        <div class='lower middle a' id='a3' ></div>
        <div class='normal middle a' id='a4' ><p>A</p></div>
        <div class='upper middle a' id='a5' ></div>   

        <div class='lower ring as' id='as3' ></div>
        <div class='normal ring as bnote' id='as4' ><p>A#</p></div>
        <div class='upper ring as' id='as5' ></div>   

        <div class='lower pinky b' id='b3' ></div>
        <div class='normal pinky b' id='b4' ><p>B</p></div>
        <div class='upper pinky b' id='b5' ></div>   

        <div id='playback'><p>Playback</p></div>
        <div id='clear'><p>Clear</p></div>
        <div id='channel'><p id='channel_label'> 0 </p></div>
        <div id='channel_up'><p>+</p></div>
        <div id='channel_down'><p>-</p></div>
</body>
</html>


Current Javascript:
(function(){
    var ip = "127.0.0.1:8080", channel = 0, channel_label;
    function update_channel(){
        channel_label.text(channel);
    }
    function up_channel(){
        if(channel<120){
            channel += 1;
            update_channel();
        }
    }
    function down_channel(){
        if(channel>0){
            channel -= 1;
            update_channel();
        }
    }
    function play_note(note){
        $.get("http://"+ip+"/midi?note="+note+"&duration=100&channel="+channel, function(){});   
    }
    $(document).ready(function(){
        var offset = 12,i = 0, notes =[
            "c",
            "cs",
            "d",
            "ds",
            "e",
            "f",
            "fs",
            "g",
            "gs",
            "a",
            "as",
            "b"
        ];
        channel_label = $("#channel_label");
        $("#playback").click(function(){
            $.get("http://"+ip+"/midiplayback",function(){});
        });
        $("#clear").click(function(){
            $.get("http://"+ip+"/midiclear",function(){});
        });
        $("#channel_up").click(function(){ up_channel();        });
        $("#channel_down").click(function(){ down_channel();        });
       
        $(notes).each(function(ni){
            var item = 60+i, note = notes[ni];
            i+=1;
            $("#"+note+"3").click(function(){
                play_note(item-offset);
            });
            $("#"+note+"4").click(function(){
                play_note(item);
            });
            $("#"+note+"5").click(function(){
                play_note(item+offset);
            });
        });
    });
}());

Screen shot:

Thursday, October 31, 2013

As the Sparks Fly Upward

Today I have a special guest co-writing my blog. None other than
Leah, my wonderful wife.

Yesterday I downloaded my favorite local artist, Tiny Rain's new album "As the Sparks Fly Upward". An introspective departure from their early works, this instrumental album has a much darker tone. Some music is just made for listening to by yourself, with headphones, at night. The recurring theme of despair and emptiness is illuminated with haunting ghosts skirting the periphery. Despite this different sound, there is a string of familiarity throughout, that makes it more like an old friend than a strange journey into the unknown.

I would highly recommend downloading it (for free, no less!) here:
http://www.noisetrade.com/tinyrain/as-the-sparks-fly-upward

or if you have time to listen to it all in one sitting:

https://soundcloud.com/user205659242

Don't forget if you can to "Leave a tip" and share on Facebook, Twitter,
G+, MySpace, with strangers next to you in traffic...

If you liked that album and want to try something a little different
from the same artists you should try their early works:

http://www.noisetrade.com/tinyrain/collected-works-2001---2007


By Carl & his lovely wife Leah.

Wednesday, October 30, 2013

Start of a Geocache

One of my favorite sites "Hack a Day" was running a contest to slap their logo on something and possibly win a Trinket by AdaFruit. Since I didn't have an ion beam to win the small category and didn't have access to any giant building light arrays I thought of a creative way to spray paint something.

A while back I had picked up two surplus ammo boxes which are perfect size for a traditional geocache. I took their logo image and made an outline of it so I could print just what I needed to cut it. After printing the outline I sliced it up and left a small strip to keep the eyes in the appropriate places. A few sprays and the logo was on. Here is a link to the article:

http://hackaday.com/2013/10/26/trinket-contest-update-2/ 

Future Geocache

Now I need to find a place to stash it. I'll probably need a nice label on the top and side and maybe a QR code to scan when it is found, or a log book for the traditional people. It would be neat to have a few electronic projects to put inside. I'm open to ideas.

Tuesday, October 29, 2013

Battery on Xmobar

The battery plugin didn't seem to work:

pacman -S bc

gives me a calculator that I can use to divide the full energy from current energy.

echo "scale=2;$(cat /sys/class/power_supply/BAT0/energy_now)/$(cat /sys/class/power_supply/BAT0/energy_full)"| bc -q

a simple cat of /sys/class/power_supply/BAT0/status
gives me charging or discharging

Heres what I've got so far:


~/.xmobarrc

Config {bgColor = "black"
       , fgColor = "yellow"
       , position = Top
       , commands = [   
            Run Com "cat" ["/sys/class/power_supply/BAT0/status"] "battstat" 1000,
            Run Com "battpercentage" [] "battcharge" 1000,
                Run StdinReader
        ]
       , sepChar = "%"
       , alignSep = "}{"
       , template = "%StdinReader%}{%battcharge% %battstat% %date%"
}   

Sound

Sound might work in gnome without additional setup, but in a bare bones enviroment some additional steps might be needed:

https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture

pacman -S alsa-utils

probably it will be muted so:

amixer sset Master unmute

or

alsamixer 

and change it


cmus will try and use pulse if you let it

switch it in the ~/.cmus/rc

set output_plugin=alsa
set dsp.alsa.device=default
set mixer.alsa.channel=Master
set mixer.alsa.device=default

What key is that?

showkey --scancodes
 
or
 
showkey --keycodes
 
or 

xev > somelogfile

Might have to install xorg-xev

See:

https://wiki.archlinux.org/index.php/Extra_Keyboard_Keys