Saturday, December 31, 2011

Monday, December 26, 2011

youtube upload #4

This time, it is Korean heavy metal.

Kim Kyungho, "Judgement Day"



Thursday, October 27, 2011

Hard to keep up the blog, thanks to twitter, G+, facebook.

Thanks to those easy to use social media, I forget my blogs more often.  I hope to get something interesting to post.  These days, I don't have any specific subjects.  Other than work and music, I don't run my side projects and researches.

Maybe I can put my "type slow" practice.  I definitely get benefit from that practice.

Thursday, September 8, 2011

My third youtube upload.


Tuesday, August 2, 2011

Classical piece

Uploaded Bach BWV 997, on clean tone with my practice guitar.
Classical sounds lovely, but following music is different from playing, even in technical perspective.


http://www.youtube.com/watch?v=aDz9yDztAfY

Friday, June 24, 2011

Code browsing (ETAGS vs. Eclipse)

I am an Emacs enthusiast, and I always try to resolve my problems in Emacs.
However, today, I gave up Etags. I don't compile codes on Eclipse, yet. For code browsing capability, Eclipse is far better and intuitive. I can't clearly distinguish/categorize properties of "This is better on Emacs" vs "This is better on Eclipse". Truely, editing task is better on Emacs, but, code browsing is better on Eclipse.

The nature of code browsing is different from actual coding.
When writing a project, the author of the project knows details up front, such as where to look, how these variables/functions are used. When modifying someone else's project, initially readers don't have a clue. The readers will collect details by asking many questions (in browsing terms, querying symbol/usage chain/see declaration/see definition/ etc... ). On emacs, interface is too flat. I use Etags often, but still I have to look up, though. On Eclipse, interface is hierarchic, and grouped based on situation.

I can't describe better than this. Sorry for rough explaining. At this point, I remember that someone mentioned "Eclipse vs. Emacs is facing the same argument of Emacs vs. Vi when Emacs got attentions first time. One example is that "Eclipse is heavy". Emacs was heavy when it appeared for the first time.

One nice tip, to browse through history, use ALT-left and ALT-right.

Tuesday, May 31, 2011

Metronome for Linux in Python

I changed my metronome.c in python to work with Windows. ( Initially, I made a mistake which errored in Windows.) I didn't distinguish binary/text mode in Windows, which doesn't matter in Linux. After adding sys.platform condition, it works, but looks a little clumsy.

To use this,
$ python metronome.py [sample_file] [bpm] [duration in sec]


For example, this command will generate "a.wav" which has 120 BPM beat for 15 sec. s3.wav is a simple beep wav in 44100 wav encode.
$ python metronome.py s3.wav 120 15


Here is the code:
#!/usr/bin/env python

import os
import sys
import struct

empty_sound = struct.pack('bbbbbbbb', *( 4,0,0,0,6,0,6,0 ))

class WavHeader(object):
def __init__(self, rawdata):
self.tup = struct.unpack("iiiiihhiihhii", rawdata)
self.chunk_id = self.tup[0]
self.chunk_sz = self.tup[1]
self.format = self.tup[2]
self.sub_chunk1_id = self.tup[3]
self.sub_chunk1_sz = self.tup[4]
self.audio_format = self.tup[5]
self.num_channel = self.tup[6]
self.sample_rate = self.tup[7]
self.byte_rate = self.tup[8]
self.block_align = self.tup[9]
self.bits_per_sample = self.tup[10]
self.sub_chunk2_id = self.tup[11]
self.sub_chunk2_sz = self.tup[12]

def pack(self):
return struct.pack("iiiiihhiihhii", self.chunk_id, self.chunk_sz,
self.format , self.sub_chunk1_id,
self.sub_chunk1_sz , self.audio_format,
self.num_channel , self.sample_rate ,
self.byte_rate , self.block_align ,
self.bits_per_sample, self.sub_chunk2_id,
self.sub_chunk2_sz )

ONE_SEC = 88200
def bytes_for_beat(bpm):
ratio = bpm/60.0
bytes_per_beep = ONE_SEC / ratio
return int(bytes_per_beep)


def main():
sample_fname = sys.argv[1]
tempo = int(sys.argv[2])
if tempo < 40:
print >> sys.stderr, "Invalid tempo: Make it between 40 - MAX"
print >> sys.stderr, " * longer the sample length, smaller the MAX"
sys.exit(1)
dura = int(sys.argv[3])
if dura <= 0:
print >> sys.stderr, "Invalid duration: Make it greater than 0"
sys.exit(2)

# Reading sample header
if sys.platform == 'win32':
rd = open(sample_fname, "rb")
else:
rd = open(sample_fname, "r")
sample_hdr = WavHeader(rd.read(44))
sample_data = rd.read()
rd.close()

# Generating Beat data as WAV, storing temp file 't.wav'
if sys.platform == 'win32':
bdata = open("t.wav", "wb")
else:
bdata = open("t.wav", "w")
tot_beats = dura * (tempo/60.0);
bps = bytes_for_beat(tempo);
tot_bytes = 0;
for i in range( int(tot_beats)):
bdata.write( sample_data )
tot_bytes += sample_hdr.sub_chunk2_sz;
for j in range( (bps - sample_hdr.sub_chunk2_sz)/8):
bdata.write( empty_sound )
tot_bytes += len(empty_sound)
bdata.close()

# Overwrite new size, and Generate output wav file 'a.wav'
sample_hdr.sub_chunk2_sz = tot_bytes
if sys.platform == 'win32':
outf = open("a.wav", 'wb')
else:
outf = open("a.wav", 'w')
outf.write( sample_hdr.pack() )
if sys.platform == 'win32':
outf.write( open('t.wav', 'rb').read() )
else:
outf.write( open('t.wav').read() )
outf.close()


if __name__ == '__main__':
main()