psychedeli.ca

100% PURE BEARD

the role of the ajax call

I wanted to touch a little on this topic in public because I feel it's something many Rails developers don't get about JavaScript. This was inspired by an email I got, as well as countless discussions I've had with both my co-workers and fellow programmers I've helped out on IRC. I think a lot of programmers could benefit from this information so you don't run into this issue yourself.

The Ajax request.

It's really nice, isn't it? You can do a lot of things with it, you can even download other JavaScript code asynchronously and execute it. This has proven, however, to be somewhat dangerous. While reviewing my co-workers' CMS code to find out why it was spitting errors out all the time, I noticed that he was constantly passing JavaScript in Ajax requests back and forth and expecting them to execute properly. While at one time they may have, for some reason now they get errors like $ is not defined, even though jquery.js is right there in the Net panel of Firebug. What it boiled down to was that our browser (Firefox) was refusing to allow access to previously loaded libraries on the page to Ajax-requested JavaScript.

This was an example in PHP, but Ruby on Rails also suffers from this potential disaster. Rails developers can create .js files that their views respond Ajax requests to. Typically, these files are JavaScript code segments that are supposed to be executed when they run. But they don't always get executed like that. Sometimes, the browser refuses to load the library, and other times the JavaScript simply fails to run, even though it's in the page. It's as if it was plain text, but not being displayed because it's in a <script> tag. This entire post was inspired by an email I got from a Rails developer attempting to pass JavaScript code and HTML simultaneously in a modal dialog. He was using the Rails JavaScript view system, a now deprecated means of transferring data between the Rails application's controller and helper layers and the JavaScript logic on the view layer.

Our Solution

We decided to solve this by changing the way we wrote Ajax requests in the CMS. It was much more efficient to use Ajax as a static data transfer mechanism, rather than a means of transferring logic code between files. So instead of getting back <script> tags with code in it, we got back JSON data and used that to execute that segment of JavaScript code. PHP makes this easy, as it allows any Array to be encoded into valid JSON. So what we did was respond with something like this

  
<?php
    header('Cache-Control: no-cache, must-revalidate');
    header('Content-type: application/json');
    $response = array(
            'status' => "success",
            'markup' => '<div class="success">Successfully saved changes to the file.</div>'
        );
    echo(json_encode($response));
?>

Instead of merely echoing that HTML in a String, we are wrapping it with JSON and returning that. Notice that you need special HTTP headers to return a valid JSON response, some browsers attempt to guess based on the content but you can't really rely on that. To ensure that the browser is interpreting this response as JSON, you must specify the HTTP Content-Type as application/json. I've also included a Cache-Control directive which forces the browser to reload the content every time it loads. This ensures that browsers won't cache these requests, because your data is always changing.

So now, we can write some JavaScript to process that data. We like to use the jQuery.form plugin at the office...

<script>
    $('#saveForm').ajaxSubmit({
        url: 'ajax/saveChanges.php',
        dataType: 'json',
        success: function(response, xhr, status) {
            $('#status').append(response.markup).slideDown(400);
            setTimeout(function() { $('#status').slideUp(400); }, 5000);
        }
    });
</script>

That extension to the jQuery library simply submits a form asynchronously, and its options Object lets you bind actions to the various jQuery.ajax callbacks.

A little philosophy

So now you know the code, but it's time to learn about why exactly I chose to do it this way.

Ajax is for transferring data, not logic

You can boil every Ajax call down to one formula: send request, receive response, execute callback(s). This is, after all, the basic format of an HTTP request. Knowing this, you can design your Ajax requests to simply be informational, then when a response is received you execute the JavaScript inside its success callback. This may be a bit confusing to debug, but it's a little easier if you extrapolate every call to a function in the same external .js file, and name your functions by the action they perform. This ensures an application that performs exactly as you expect it. You'll never have to hunt through HTML code in an Ajax response, nor will you ever have a question as to what type of content you're getting from this particular HTTP request.

Standardize your JSON response

Once you've gotten this pattern down, it's important to keep a standard practice when creating your JSON responses. Lets say you want to GET an object, like a Post, from your blog. Fortunately, you've written a small PHP script that will return it from the database. Let's just say, for shits and giggles (and because it's almost 2:00am and I don't feel like writing it out), that this PHP script works and returns the following JSON response:

<?php
    $id = $_GET['id'];
    $sql = "SELECT title, body FROM `posts` WHERE `id` = '$id'"
    $response = mysql_query($sql, mysql_connect('localhost', 'user', 'pass', 'database'));
    
    if (count($response)) {
        echo json_encode($response);
    } else {
        echo json_encode(array('message' => "Error: Shit don't work!"));
    }
?>

Right now, this doesn't follow a standard practice. response.message would have to be tested on the client side to see if this is an error or not. That's no way to do business, especially if you may need multiple messages or styles for each message. A better way to create this JSON would be to do

<?php
    $id = $_GET['id'];
    $sql = "SELECT title, body FROM `posts` WHERE `id` = '$id'"
    $post = mysql_query($sql, mysql_connect('localhost', 'user', 'pass', 'database'));
    
    if ($id && count($post)) {
        $response = array(
            'type' => 'success',
            'post' => $post
        );
    } else if (count($post)) {
        $response = array(
            'type' => 'warning',
            'message' => "Post not found"
        );
    } else {
        $response = array(
            'type' => 'error',
            'message' => "No ID passed"
        );
    }
    
    header('Cache-Control: no-cache, must-revalidate');
    header('Content-type: application/json');
    
    echo json_encode($response);
?>

We know that if response.type is "success", then response.post will be defined and we can work with it. But if response.type is "error", we will know that response.message is defined and we need to display it. The JavaScript can use a switch statement to parse other types of messages like "warning" or "info", which we may use in the future. Altering your JSON responses to be standard now will save you much testing and coding time in the future. Observe how much more informative these error messages are, and how much more flexible your code is after this alteration.

Posted in code

Tags: #ajax,#javascript,#rails | Comments

innovators with the biggest impact on society

A response I made to a thread on the Something Awful forums:

Tim Berners-Lee is the innovator who made the biggest impact on society. He created the Web and laid out guidelines to ensure that it would never become the capitalist nickel-and-dime cesspool that the Mobile Web was created to be. Instead, he built the Web to enforce open-source principles (go ahead, try and hide your JavaScript code from me...), and released it to academia first to ensure it would grow as an information hub rather than a marketing tool. While others have taken the Web and warped it for their own financial interests, Tim Berners-Lee has contented to teach and further the concept of a place where humanity could finally be free to experience anything they wanted, or learn about anything they wanted, in seconds.

In my opinion, the Web is still the only 24/7 place in the world where you can really say and do anything you want. It's the reason why most of the music industry has come to terms with the fact that doing your own thing and doing what you love to do is the ONLY reason to be a musician these days, because the Internet and the principles of the WWW have made it so the labels can't control the industry anymore. It's no longer a legal monopoly. Web connectivity is the major reason why the Arab Spring protests could even happen in the first place, without government control they were able to access new ideas and organize effectively. The anger has been in their blood since the 60's, but the Web made it all coalesce so it could drive their oppressors out of the country.

Not only that, but Tim continues to contribute to the Web's ecosystem and publishes papers and articles commenting on the state of the Web, how certain companies are furthering its intended purpose and how some of them are actually diminishing it.

So yeah. Have any of the people mentioned thus far built technology that allowed a revolution to happen? Not a revolution involving the exchange of money, but a REAL one?

Interesting how much advertising affects our life that we miss some of the great innovators simply because they didn't want to/have to market their product.

Posted in gbs

Tags: TimBerners-Lee,SteveJobs,BillGates | Comments

a new beginning

So here we go, another new layout and another re-hash of this blog's content. I threw away the last two iterations (still have the data, though) of this blog, because I was unsatisfied with the poor content on it. So let's start again.

This will be a blog about programming, music, philosophy, and everything in between.

first of all, the blog

This blog is not in its final design. I just felt like I needed a place online to express my feelings and my experiences throughout life, and regardless of what it looks like I feel as though it needs to be on my domain, at all costs. That's why I've made deployment as easy as possible. All I have to do is a git push to my remote server, and the hook on the remote will generate the Jekyll site on http://psychedeli.ca, which will then push the update directly to the userbase. Pretty nifty, I think!

burning man

I'll be attending Burning Man this year, but I will not be performing. Instead of gifting music to the playa, I've decided to make this year my vacation. Sometimes I tend to get rather stressed out before and after performing, and I don't want that to encroach on my good time this year on the playa. This year, I'll be gifting something very different to the denizens of Black Rock City. In exchange for a free ride to and from the playa, I'll be driving a 24' Budget truck for another camp, Club Verboten, out of Reno. This is interesting on two levels: First of all, while I have driven rental trucks I've never driven one this big, so that's going to be an adventure in itself getting onto the desert in this thing. Second, I'm going to arrive in Black Rock City about two days before the festival starts. I hear it's a great time, and a unique experience in and of itself, to see the playa before it's really built up.

the wonder bars

We're currently recording our first album! Aaron and Jules and I are prepared to do live recordings of the instruments and finally realize a project that's been literally two years in the making. We have not decided on how we are going to distribute this album. We also have not determined the length of the album just yet, as I've begun to collaborate with other members of the band on a few more tracks than the initial planned 12 that I've written entirely. A full post about that is coming soon.

i'll be seeing you

Well, that's about it. I'm committed to writing more in this thing about my future experiences, as I think it would be a good idea for my own mental health if I could get a lot of these feelings off my chest.

Posted in gbs

Tags: burningman,jekyll,ruby,javascript,wonderbars | Comments

incorporating ultrabeat into my workflow

Thanks to The Architech coming over and showing me some of the more interesting features of Ultrabeat, my drum composition has changed tremendously. I used to use ReDrum, a noble and wonderful little drum machine packaged into Reason, because of its familiar look-and-feel (its UI is modeled after the TR-909) and dead-simple feature set that was not only easy to comprehend, but easy to manipulate in a live setting. But composing in ReDrum has its drawbacks, and composing in Ultrabeat works better with the way I think drums ought to be composed in electronic music. However, this presents an interesting problem: since my live setup relies on Reason for drum beats, how am I going to get Ultrabeat patterns and sounds in Reason?

a little evangelism

Starkey turned me onto Ultrabeat at my last semester of UArts during a L.A.C.E. (Laptop And Controller Ensemble, a short-lived ensemble group established by Starkey and composed of UArts students who had an interest in live electronic performance) rehearsal one Tuesday night. He builds all his beats with the plugin, but the way he introduced it to me was describing a bug he had where it CRASHED Logic! Not a really good place to start...leaving me a little prejudice against its reliability until I had a conversation with Architech a few months ago at an Arts Garage party. It eventually led to him coming over to check out the empty room in my house (which he didn't take) and us educating each other about music. One of the most interesting things he taught me was some of the concepts of Ultrabeat that are really, really cool, and basically devalue my earlier reasons for not using the plugin.

the old-fashioned way

I'd like to illustrate my former workflow for dealing with drums. The major problem with drums, and this is why they can't just be bounced and used like any other track, is that the sound of all the other tracks revolve around the sidechain compression of the kick and/or snare. So these tracks need to be extrapolated at all times so the compressors can use them as keys for the sidechain. This is a major component of the house sound in general (plus, it sounds cool), and thus needs to be carried over into live performance from the studio. While screwing around during a rehearsal, I discovered that Reason files can be opened/closed at will without affecting the sequencer, so when I have one .rns file open and open another one simultaneously, I can close the first one without affecting the sound of the sequencer. Hopefully. There have been times where the computer simply gets overloaded and can't handle all that instruction at once, wherein the sound "hiccups" a little. To date, this has never happened to me in a live performance, but I still don't want to risk it. There must be a cleaner way to do this...

the new hotness

Ultrabeat is like any other drum machine. It's got a 32-square pattern sequencer and 16 separate sample tracks, each with their own dynamics control (as if they were just normal Logic tracks), and additional options for crafting the drum sound like a drum synth, filters and envelope definition. There can be an unlimited amount of patterns stored inside the plugin itself, but I almost never save my patterns, instead opting to click the grid icon next to the pattern chooser and dragging the current pattern into Logic's arrangement window, where it is added to the Ultrabeat track as MIDI. This MIDI controls the entire drum machine, allowing you to create "evolving" beats that can change every 2 bars (or longer), and so you can easily see which patterns are being invoked on each measure. By using Ultrabeat, and adopting a more MIDI-centric workflow, my new songs have taken on quite a different character in the drum track. Since it's so much easier now to create different types of beats in my drum machine, I'm able to push further and explore more variants of beats.

One of the things I like about Ultrabeat's UI is that it can be altered to fit your current workflow. What if you have the sounds you're looking for, but you want to actually sit down and write the pattern? Hit "Pattern view" and the sound-editing options will disappear, leaving you with a huge grid to play with. But what if that kick is filtered a little too high? No problem, just click the track and hit "Full view" to bring up the sound editing options, where you can alter the filter. Notice that below the editor, you can edit the pattern for just this track. Reason users may find this interface to be a little more at-home ( I know I did) because you're used to editing one track at a time. But I strongly recommend moving over to the pattern view way of composing, it's much easier to create cleaner drum tracks that don't collide with each other.

So Ultrabeat is a great interface for working with drums, but how about controlling the sound after the drums have been synthesized? 99% of the time, I have to apply some mastering plugins to get the drum sound I want out of Ultrabeat and my TR-808/909 samples. With Reason, I was able to totally control the routing of each drum track and establish compression/filtering for each separate drum sound. This gave each of my tracks a professional, heavy and floor-filling sound that was quite malleable yet easy to deal with. My father once told me that production-wise, the foundation of the track, drums and bass normally, may be the most important elements of the whole song, and I've always strived to make this foundation both interesting and prominent, regardless of the genre I'm working with. It may also be a reason for why I enjoy creating electronic music, and house/dance specifically, because of this attention paid on the foundation. It's just not House without a booming kick & funky bass line!

This is where it gets interesting. Because Ultrabeat is built into Logic, we can actually create Aux tracks from the drum kit itself, and extrapolate some of the drums into their own separate mono tracks. From here, we can EQ, add effects and generally craft each drum sound just the same as we could with Reason. You can even apply separate automation for each drum aux and really get down-and-dirty with controlling the sound. After learning all of this, I decided it was time to finally abandon ReDrum for composing, and totally immerse myself into this new plugin that greatly accelerated my workflow and taught me a LOT about Logic.

bringing it all back home

So now I have these new tunes created in Ultrabeat, but how do I play them live? This question plagued me for weeks after I realized a month ago I would need to somehow extract these drum parts and use them in Ableton. But Ableton doesn't support Ultrabeat, so a major disconnect was taking place. My old workflow used Reason for the drums, so it was easy to just open the file in ReWired Ableton and play it through a couple audio tracks. But now that I no longer use Reason to compose drums in, I need to figure out a way to migrate the drum patterns I come up with into a sequences I can trigger easily and efficiently.

After doing some tests, I discovered that Ultrabeat's MIDI output is standardized General MIDI for drums, and therefore can be imported directly into Ableton Live (each region even becomes its own clip!) and pumped via ReWire to the Reason instance. My Reason files are now simply used for saving the preset sounds of each song's drum kit, and Ableton will now sequence the patterns like it was meant to do originally.

This part is actually a little confusing, but it makes sense in the end. What you have to do is select the MIDI regions you want in Logic (I usually group by song form: verse beats, chorus beats, etc.) and go to File > Export.. > Selection as MIDI File, and then create a new directory called "MIDI Files" in your Logic project folder. Name the file after its form name, so "drums-verse.mid", etc. This allows you to use MIDI in other ways, like for example if you use a VST you can simply open the VST in Ableton and pump in MIDI/presets you created in Logic. This allows you to alter the sound on the fly for your particular PA system (they're all different, I find myself doing a lot of audio engineering work at the beginning of a set to make the speakers react to my music properly).

To import this MIDI into Ableton, create a new MIDI track for holding drum patterns (I called mine "Drums"), and simply track the .mid file into the track. The clips will show up horizontally, simply drag them into subsequent vertical rows in your Live Set to establish a proper order for the drums to go in. By clicking these clips directly, you can invoke the MIDI for each drum pattern.

In Reason, create a new file and remove the mixer. Add in a ReDrum plugin instance and set up the drums in exactly the same order as you have them in Ultrabeat. So for example, if your drum sample order looks like: kick, snare, claps, open hat, closed hat, ride in Ultrabeat, that's what you'd want in Reason. Mute out the tracks that aren't pre-set this way to avoid wayward notes triggering drums that aren't set up properly. Hit "Tab" to get the routing panel, and route the kick & snare into separate aux channels in Reason's hardware interface patchbay, then take those channels as input into Ableton for your kick & snare tracks. This will extract just the kick & snare into separate tracks so you can set sidechains for them in other instruments. Ableton's compressor has sidechain built in now, so no need for extra VSTs taking up your memory!

So now you have Reason set up to read MIDI from Ableton, and to pump drum audio back into the sequencer through 3 separate tracks. This is the way I do things live and at home, and I hope it helps your workflow because it's certainly helped mine!

Posted in music

Tags: ultrabeat,logic,reason,abletonlive,performing | Comments

decisions, decisions

Well I'm stuck in a bind. I can't seem to decide which operating system I want to run my all-powerful file server. A few days ago, my wonderful sister gifted me two computers, the Dell OptiPlex GX270 and GX280. The basic difference between these two tried-and-true workhorses is the graphics card interface-the GX280 includes a PCI Express x16 slot whereas the GX270 is still using AGP-and of course the model number. Other than that, they use the same motherboard, same case design, and same basic layout. PERFECT for general hackery purposes...and running a Boxee...

So my first endeavor with these machines is something I've been needing for a long time: a file server to host all of the house's media. Everyone who lives in my house utilizes the internet or computers mostly for their media needs, and we've been longing for a way to experience it on a bigger screen. But a problem arises: These machines do not have the ability to pump S-Video to my regular TV, so I'm gonna need to wait a couple days before actually going ahead and opening up the boxes. I also need SATA cables and a SATA-to-IDE converter because the Dell OptiPlex motherboards come with IDE by default! By using both the SATA connector and the IDE connector adapted to a SATA connection, I'll be able to run a software RAID-0 array, mirroring the contents of the 1TB of space inside the box and therefore providing a greater level of security and stability to the system as a whole. With all of the hits it will be getting, this is a crucial step in extending the server's lifespan.

This is actually a good thing, because it gives me a bit more time to decide on an operating system. What I need is very simple, I've boiled it down to only a few requirements:

  • I want ZFS. It's amazing, the technology we have today. ZFS is this wonderful file system developed by the good ol' boys over at Sun Microsystems (now Oracle) that addresses many of the problems of former filesystems and even some of the problems of magnetic hard drives themselves. ZFS even introduces new features like built-in SMB/Netatalk capabilities, making it a lot easier to transfer data from the server to the computers where it will actually be useful.

  • I want complete Boxee transparency. The Boxee will be the major customer of this server, constantly pulling data from the media drive "/Zappa" to fulfill its users demands of the music library. Now that all music can be accessed from the living room's 3-way stereo system, I'm predicting that my roommates will be hitting the Boxee a lot more, and thus the fileserver.

Right now, my best option is FreeNAS, it's a distribution of FreeBSD (an OS I know and love) that's specially formulated to act as a network storage device. Precisely what I'm looking for! It's even bundled with a DAAP server and NFS so the Boxee can be "tricked" into thinking /Zappa is actually a part of its own local filesystem. The possibilities are endless, allowing for seamless integration of the data on these disks to the entire network here at 1913.

I think my choice has been made.

UPDATE: My FreeNAS file server is running smoothly, fully jailed. Story at 11.

Posted in code

Tags: unix,operatingsystem,hardware,boxee,freenas | Comments