Monday, November 1, 2010

カノンロック-失恋疾走曲- — 波音リツ

I've been lurking on ニコニコ動画 for quite some time and have amassed quite a collection. Here's one of my favorites by 波音リツ, a voicebank and character for a free speech synthesis program called UTAU. This song is to the tune of Canon Rock, which itself is derived from the famous song by Johann Pachelbel.

もぅ、いつも話しかけてきてくれたくせに
私と一緒にいて喜んでたのは誰なのよ

ずいぶんとお高いのですね
私を振るなんて何様のつもりでしょうか
いつも夜に布団の中で貴方の顔を
いつも思い出してあげたくらい

「‥‥それほど好きだったのに」

春の風と君への想いが箱の中で死んでゆく
まるで窓の外の桜の花びら雨に濡れて濁ってくかの様
いつの間にか君(あなた)の答えに木曽や四月の桜狩り
そんなひどい事は聞きたくなかった
いっそのこと、死んじゃえばいいのに

もう…考えてあげた時間を返して下さい
眠れなかった時間もね 全てをよ

「好きな人がいるからごめん」とかw
私を馬鹿にしているのでしょうか?

私があなたを好きなのよ
何がいけないというのでしょう

窓の外は桜の夕立ち部屋の中に降り注ぐ
桜の花びらに乗ってしまったのなら
いつかの君がいる世界へ
君のせいで私が作った明日が綺麗に崩れてくの
神サマがもし仮にいたとしたのなら
私の何が悪かったのでしょうか

(The forgotten thing. put in case and put)
("yesterday... happiness" in thrusting)

(Because it becomes a desire)
(going out if time passes...)
(あの日の事も、この日の事も考えてみれば全て嘘。)
(そう全てが嘘だったからこの感情も全部嘘。)
(考えてみると全ておかしかった。)
(彼の為に髪型を変えたり、登校時間を合わせてみたり、こっそり後ろを歩いたり、)
(まるで私が私じゃなかった様。何をしていたんだろうか。)
(でももうそんなことはしなくていい。)
(これからはしたい事をしよう。)

彼と今の悲しい気持ちは窓から射す夕日なの
桜の花のように散ってしまったから
変われる様な気がした。それなのに
空と目にはいつ日か見たよなつたっていくだけの流れ星‥
だけど、これは苦しさとかじゃないのよ。今までの
「ありがとうの気持ち?」

初めて気づいたこの気持ちは何なんだろう
"………"

「ありがとうとさようなら」
気づいたのこの気持ち
昨日とは違う 新しい朝が始まります。

「好きだよ」って聞きたかったけどもう無理なのよ…
もう知らないけど、君の為
今日だけは泣いてあげるかな

Source of lyrics above.

Thursday, August 12, 2010

Eliza vs. Eliza

What happens when you sic Chatbot::Eliza on itself? Well, you've come to the right place to find out!

#!/bin/env perl -w
use warnings;
use strict;
use utf8;
use Chatbot::Eliza;

my ($bot1, $bot2) = (new Chatbot::Eliza, new Chatbot::Eliza);

my $text = "Hello.";
print "Me: $text\n";
for(1..100) {
if($_ % 2) {
$text = $bot1->transform($text);
print "Eliza #1: $text\n";
}
else {
$text = $bot1->transform($text);
print "Eliza #2: $text\n";
}
}
Me: Hello.
Eliza #1: Hi. What seems to be your problem?
Eliza #2: Does that question interest you?
Eliza #1: You're not really talking about me -- are you?
Eliza #2: What makes you think I am not really talking about you -- are me?
Eliza #1: What makes you think I -- are you?
Eliza #2: Oh, I?
Eliza #1: Why do you say you?
Eliza #2: We were discussing you -- not me.
Eliza #1: Do you wish to believe I -- not you?
Eliza #2: You're not really talking about me -- are you?
Eliza #1: What makes you think I am not really talking about you -- are me?
Eliza #2: Really, I -- are you?
Eliza #1: Oh, I?
Eliza #2: Can you elaborate on that?
Eliza #1: Oh, I elaborate on that?
Eliza #2: Do you say you elaborate on that for some special reason?
Eliza #1: We were discussing you -- not me.
Eliza #2: Do you wish to believe I -- not you?
Eliza #1: We were discussing you -- not me.
Eliza #2: Really, I -- not you?
Eliza #1: Oh, I?
Eliza #2: Why do you say you?
Eliza #1: You're not really talking about me -- are you?
Eliza #2: Does it please you to believe I am not really talking about you -- are me?
Eliza #1: Why do you think I -- are you?
Eliza #2: Oh, I?
Eliza #1: Why do you say you?
Eliza #2: What are your feelings now?
Eliza #1: Have you asked such questions before?
Eliza #2: We were discussing you -- not me.
Eliza #1: Really, I -- not you?
Eliza #2: You're not really talking about me -- are you?
Eliza #1: Do you sometimes wish you were not really talking about you -- are me?
Eliza #2: Really, I -- are you?
Eliza #1: We were discussing you -- not me.
Eliza #2: Suppose I did -- not you -- what would that mean?
Eliza #1: We were discussing you -- not me.
Eliza #2: Suppose I did -- not you -- what would that mean?
Eliza #1: You're not really talking about me -- are you?
Eliza #2: Do you sometimes wish you were not really talking about you -- are me?
Eliza #1: Does someone else believe I -- are you?
Eliza #2: Oh, I?
Eliza #1: That's quite interesting.
Eliza #2: Tell me more about that.
Eliza #1: Please go on.
Eliza #2: Does talking about this bother you?
Eliza #1: You're not really talking about me -- are you?
Eliza #2: Perhaps you would like to be not really talking about you -- are me.
Eliza #1: Do you wish to believe I -- are you?
Eliza #2: We were discussing you -- not me.
Eliza #1: Why do you think I -- not you?
Eliza #2: You're not really talking about me -- are you?
Eliza #1: Do you sometimes wish you were not really talking about you -- are me?
Eliza #2: Does someone else believe I -- are you?
Eliza #1: You're not really talking about me -- are you?
Eliza #2: Does it please you to believe I am not really talking about you -- are me?
Eliza #1: What makes you think I -- are you?
Eliza #2: You're not really talking about me -- are you?
Eliza #1: What makes you think I am not really talking about you -- are me?
Eliza #2: Really, I -- are you?
Eliza #1: What are your feelings now?
Eliza #2: What is it you really want to know?
Eliza #1: What are your feelings now?
Eliza #2: What do you think?
Eliza #1: You're not really talking about me -- are you?
Eliza #2: Perhaps you would like to be not really talking about you -- are me.
Eliza #1: What makes you think I -- are you?
Eliza #2: We were discussing you -- not me.
Eliza #1: Really, I -- not you?
Eliza #2: Oh, I?
Eliza #1: Why do you say you?
Eliza #2: You're not really talking about me -- are you?
Eliza #1: What makes you think I am not really talking about you -- are me?
Eliza #2: You like to think I -- are you -- don't you?
Eliza #1: We were discussing you -- not me.
Eliza #2: Suppose I did -- not you -- what would that mean?
Eliza #1: We were discussing you -- not me.
Eliza #2: Do you wish to believe I -- not you?
Eliza #1: You're not really talking about me -- are you?
Eliza #2: Perhaps you would like to be not really talking about you -- are me.
Eliza #1: Really, I -- are you?
Eliza #2: You're not really talking about me -- are you?
Eliza #1: Perhaps you would like to be not really talking about you -- are me.
Eliza #2: What makes you think I -- are you?
Eliza #1: Oh, I?
Eliza #2: That's quite interesting.
Eliza #1: Please go on.
Eliza #2: That is interesting. Please continue.
Eliza #1: Tell me more about that.
Eliza #2: Does talking about this bother you?
Eliza #1: What are your feelings now?
Eliza #2: Have you asked such questions before?
Eliza #1: We were discussing you -- not me.
Eliza #2: You like to think I -- not you -- don't you?
Eliza #1: Oh, I?
Eliza #2: Do you say you for some special reason?
Eliza #1: Oh, I for some special reason?
Eliza #2: Do you say you for some special reason for some special reason?
Eliza #1: We were discussing you -- not me.
Eliza #2: Does someone else believe I -- not you?

Yeah, it's not as interesting as one would think.

Friday, July 23, 2010

Converting Between Tabs and Spaces

If you want to use tabs in Python but everyone else uses spaces, here's something helpful you can do in git!

% echo '*.py filter=tabspace' >> .git/info/attributes
% git config --global filter.tabspace.smudge 'unexpand --tabs=4 --first-only'
% git config --global filter.tabspace.clean 'expand --tabs=4 --initial'

You can appear to comply with PEP-8 to others using your repository, but you don't need to change your habits!

Thursday, June 10, 2010

ALSA, dmix, and X-Fi

I was having all sort of issues getting my SoundBlaster X-Fi working properly using the snd-ctxfi module. First off, I got something about "invalid sw-parameters," and once I had fixed that by going through dmix I lost the ability to have multiple streams playing at once.

Eventually I found a middle ground that had everything working, with the bonus of pretty sweet upmixing, all by putting this in my asound.conf:

pcm.!default {
type plug
slave {
pcm "duplex"
channels 6
}
ttable {
0.0 1
1.1 1
0.2 1
1.3 1
0.4 0.5
1.4 0.5
0.5 0.5
1.5 0.5
}
}

pcm.snd_card {
type hw
card 0 # SoundBlaster X-Fi
}
pcm.s51 {
type plug
slave {
pcm "surround51"
rate 48000
channels 6
}
}



pcm.duplex {
type asym
playback.pcm "s51"
capture.pcm "snd_card"
}

It looks like pushing everything through surround51 (though not directly) works perfectly.

Monday, March 15, 2010

flatten2.py

After reading about OptiPNG, I decided to add it into the mix of flatten.py. Since it doesn't support reducing bit depths of grayscale images, I have the script run pngcrush first and then OptiPNG.

Since the last post about flatten, I've made a few other changes as well, such as passing -bit_depth to pngcrush when a bit depth is provided. Since I use this script to compress images for my webcomic, that's an important change.

flatten.py

#!/usr/bin/python
from sys import argv, stderr, exit
from subprocess import Popen
from optparse import OptionParser, OptionValueError
from copy import copy
from os import remove
from os import close as os_close
from re import compile as re_compile
from os.path import join, isfile
from tempfile import mkstemp


size = re_compile('^(.+)x(.+)$')

def check_size(option, opt_str, value, parser):
m = size.search(value)
if m:
parser.values.size = m.group(1), m.group(2)
else:
raise OptionValueError('Invalid size: %s' % value)

filext = re_compile('^(.+)\.(.+)$')
filext_png = re_compile('\.png$')

img_type = ['Bilevel', 'Grayscale', 'GrayscaleMatte', 'Palette', 'PaletteMatte', 'TrueColor', 'TrueColorMatte', 'ColorSeparate', 'ColorSeparationMatte', 'Optimize']
img_cspace = ['CMY', 'CMYK', 'Gray', 'HSB', 'HSL', 'HWB', 'Lab', 'Log', 'OHTA', 'Rec601Luma', 'Rec601YCbCr', 'Rec709Luma', 'Rec709YCbCr', 'RGB', 'sRGB', 'Transparent', 'XYZ', 'YCbCr', 'YCC', 'YIQ', 'YPbPr', 'YUV']
pngcrush = ['pngcrush', '-rem', 'gAMA', '-rem', 'cHRM', '-rem', 'iCCP', '-rem', 'sRGB']

parser = OptionParser(usage = 'Usage: %prog [ options ] input [ output ]')
parser.add_option('-s', '--size', dest = 'size', type = 'string', action = 'callback', callback = check_size, default = None, help = 'The output size: WIDTHxHEIGHT')
parser.add_option('-n', '--no-clobber', dest = 'clobber', default = True, action = 'store_false', help = 'The output size: WIDTHxHEIGHT')
parser.add_option('-f', '--filter', dest = 'filter', default = 'Catrom', help = 'The filter to resize with if necessary.')
parser.add_option('-b', '--background', dest = 'background', default = 'white', help = 'The background when flattening.')
parser.add_option('-F', '--no-flatten', dest = 'flatten', default = True, action = 'store_false', help = 'Don\'t flatten the output.')
parser.add_option('-t', '--type', dest = 'type', type = 'string', default = None, help = 'The type of the output image: analogous to both -type and -colorspace in ImageMagick')
parser.add_option('-d', '--depth', dest = 'depth', type = 'int', default = None, help = 'The depth of the output image.')

options, args = parser.parse_args()
if len(args):
input = args.pop(0)
if isfile(input):
output = None
pngout = False
if len(args):
output = args.pop(0)
if filext_png.search(output):
pngout = True
else:
m = filext.search(input)
if not m is None:
output = '%s_small.%s' % (m.group(1), m.group(2))
if m.group(2) == 'png':
pngout = True
else:
output = '%s_small.png' % input
pngout = True
if not options.clobber and isfile(output):
print >>stderr, 'Output file exists:', output
exit(2)
# ACTUAL PROCESSING
args = ['convert', input]

if not options.type is None:
if options.type in img_type:
args += ['-type', options.type]
if not options.depth is None:
args += ['-depth', str(options.depth)]
elif options.type in img_cspace:
args += ['-colorspace', options.type]
if not options.depth is None:
args += ['-depth', str(options.depth)]
if options.flatten:
args += ['-background', options.background, '-flatten', '+matte']
if not options.size is None:
args += ['-filter', options.filter, '-resize', '%sx%s' % options.size]


if pngout:
# Run convert
fd, tmpfile = mkstemp()
os_close(fd)
args.append('png:' + tmpfile)
Popen(args).communicate()
# Run pngcrush
args = copy(pngcrush)
if not options.depth is None:
args += ['-bit_depth', str(options.depth)]
args += [tmpfile, output]
Popen(args).communicate()
remove(tmpfile)
# Run optipng
Popen(['optipng', '-o9', output]).communicate()
else:
args.append(output)
Popen(args).communicate()
# END
else:
print >>stderr, 'No such file:', input
exit(2)
else:
parser.print_help()
exit(1)

The runtime options are the same as flatten.py.

Sunday, January 31, 2010

Grok

A friend of mine wrote a Python script to replace Ack (which is much faster than grep) and the resulting script turned out to be significantly faster than it. I decided then to write my own rough equivalent, called 'grok' (name from another similar program):

grok.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pcre.h>
#include <dirent.h>
#include <limits.h>
#define BLOCK_SIZE 1024
#define OFFSET_COUNT 1
struct {
char * bytes;
off_t length;
} blocks = {NULL, 0};


int search(const char * path, pcre * re) {
FILE * input = fopen(path, "r");
off_t n = 1;
int ovector[OFFSET_COUNT];
int rc;
char first_match = 1;
if(!input) {
perror(path);
return 1;
}
if(!blocks.bytes && !blocks.length) {
// Initialize blocks on first time
blocks.bytes = malloc(BLOCK_SIZE);
memset(blocks.bytes, '\0', BLOCK_SIZE);
blocks.length = BLOCK_SIZE;
}
// Search
while(!feof(input)) {
// Read a line
blocks.bytes[blocks.length - 2] = '\0'; // [blocks.length - 1] will always be '\0' due to fgets() behavior
fgets(blocks.bytes, blocks.length, input);
//printf("%lu/%lu; %d\n", strlen(blocks.bytes), blocks.length, blocks.bytes[blocks.length - 2]);
while(!feof(input) && blocks.bytes[blocks.length - 2] && blocks.bytes[blocks.length - 2] != '\n') {
// Expand blocks as necessary
blocks.length += BLOCK_SIZE;
blocks.bytes = realloc(blocks.bytes, blocks.length);
blocks.bytes[blocks.length - 2] = '\0';
fgets(blocks.bytes + strlen(blocks.bytes), BLOCK_SIZE + 1, input);
//printf("%lu/%lu; %d\n", strlen(blocks.bytes), blocks.length, blocks.bytes[blocks.length - 2]);
}
if(!(feof(input) && !*blocks.bytes)) {
n++;
rc = pcre_exec(re, NULL, blocks.bytes, strlen(blocks.bytes), 0, 0, ovector, OFFSET_COUNT);
if(rc < 0) {
switch(rc) {
case PCRE_ERROR_NOMATCH:
break;
case PCRE_ERROR_BADUTF8:
fprintf(stderr, "Bad UTF-8 at line %lu in %s\nSkipping file (try running with -U option to disable Unicode).\n", n, path);
fclose(input);
return 1;
break;
default:
fprintf(stderr, "Error: %d\n", rc);
break;
}
blocks.bytes[0] = '\0';
continue;
}
if(first_match) {
first_match = 0;
printf("%s:\n", path);
}
printf("%6lu:%s", n, blocks.bytes);
blocks.bytes[0] = '\0';
}
}
// Cleanup
fclose(input);
return 0;
}

int recursive_search(const char * path, pcre * re) {
DIR * dirinfo;
struct dirent * file;
struct stat info;
char fullpath[PATH_MAX], * filepart;
if(!stat(path, &info)) {
if(S_ISREG(info.st_mode)) {
// Regular files
if(search(path, re) == -1)
return -1;
}
else if(S_ISDIR(info.st_mode)) {
// Directories
strcpy(fullpath, path);
strcat(fullpath, "/");
filepart = fullpath + strlen(fullpath);
dirinfo = opendir(path);
while((file = readdir(dirinfo)) != NULL) {
if(*file->d_name != '.') {
strcpy(filepart, file->d_name);
if(recursive_search(fullpath, re) == -1)
return -1;
}
}
closedir(dirinfo);
}
}
else
perror(path);
return 0;
}


int main(int argc, const char * argv[]) {
// Defaults
const char * default_dirs[] = {"."};
const char * progname = *argv;
// General Variables
const char ** dirs;
int erroroffset;
int options = PCRE_UTF8;
off_t i, dirs_length;
const char * error;
pcre * re;
// Initialization
argc--; argv++;
// Parse flags
while(argc && (*argv)[0] == '-' && (*argv)[1] != '-') {
switch((*argv)[1]) {
case 'i':
options |= PCRE_CASELESS;
case 'U':
options &= ~PCRE_UTF8;
case '\0': break;
default:
fprintf(stderr, "Invalid option: %s", *argv);
return -1;
break;
}
argc--; argv++;
}
// Parse arguments
if(argc) {
re = pcre_compile(*argv, options, &error, &erroroffset, NULL);
if(argc > 1) {
dirs = argv + 1;
dirs_length = argc - 1;
}
else {
dirs = default_dirs;
dirs_length = 1;
}
}
else {
fprintf(stderr, "Usage: %s [ -i ] [ -u ] expr [ path1 .. pathN ]\n", progname);
return 1;
}
if(!re) {
fprintf(stderr, "PCRE compilation error at offset %d: %s\n", erroroffset, error);
return 2;
}
// Recursive search
for(i = 0; i < dirs_length; i++) {
if(recursive_search(dirs[i], re) == -1) {
fputs("Ran out of memory.", stderr);
return 128;
}
}
// Cleanup
if(blocks.bytes && blocks.length) {
free(blocks.bytes);
blocks.bytes = NULL;
blocks.length = 0;
}
pcre_free(re);
return 0;
}

As it turns out, my program is able to run twice as fast as his on a given directory tree (small to large).