From 99214bb73d623cd9b22fd0e1bf121a73ab209eca Mon Sep 17 00:00:00 2001 From: divide Date: Wed, 6 Feb 2008 10:40:15 +0000 Subject: [PATCH] Fast scrambling courtesy of a C function. git-svn-id: file:///home/divide/svn/trunk/walkgirl/trunk@417 92f4db9c-a619-0410-8c93-89f5936be7a8 --- walkgirl/audiofile.rb | 23 +++++++++--------- walkgirl/extconf.rb | 25 +++++++++++++++++++ walkgirl/mp3.rb | 36 ++++++++++++++++----------- walkgirl/nwscrambler.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 26 deletions(-) create mode 100644 walkgirl/extconf.rb create mode 100644 walkgirl/nwscrambler.c diff --git a/walkgirl/audiofile.rb b/walkgirl/audiofile.rb index 94462d7..d627d25 100644 --- a/walkgirl/audiofile.rb +++ b/walkgirl/audiofile.rb @@ -84,28 +84,27 @@ module NetworkWalkman end def save - File.open(filename, 'r+') {|outfile| + File.open(filename, 'w+') {|outfile| tag = ID3::Tag2.new if tags # convert to ID3v2 tags.each { |key, value| tag[key] = value tag[key] = tag[key].recode(2) if tag[key]["text"] - p tag } end tag = tag.dump tag[0...10] = ["ea3", 3, 0x1776].pack("a3c@8n") - p tag - outfile.seek(0) - outfile << [tag].pack("a3072") + outfile.sysseek(0, IO::SEEK_SET) + outfile.syswrite [tag].pack("a3072") # write out header - outfile << "EA3" - outfile << [2, 0, 0x60, 0xff, 0xfe, 1, 0x0f, 0x50, 0x00].pack("c5@9c4") - outfile << [0, 4, 0, 0, 0, 1, 2, 3, 0xc8, 0xd8, 0x36, 0xd8, 0x11, 0x22, 0x33, 0x44].pack("c*") - outfile << [0x03, 0x80, encoding, 10, length, frames, 0].pack("c4N3") - outfile << [0,0,0,0].pack("N4") - outfile << [0,0,0,0].pack("N4") - outfile << [0,0,0,0].pack("N4") + outfile.syswrite "EA3" + outfile.syswrite [2, 0, 0x60, 0xff, 0xfe, 1, 0x0f, 0x50, 0x00].pack("c5@9c4") + outfile.syswrite [0, 4, 0, 0, 0, 1, 2, 3, 0xc8, 0xd8, 0x36, 0xd8, 0x11, 0x22, 0x33, 0x44].pack("c*") + outfile.syswrite [0x03, 0x80, encoding, 10, length, frames, 0].pack("c4N3") + outfile.syswrite [0,0,0,0].pack("N4") + outfile.syswrite [0,0,0,0].pack("N4") + outfile.syswrite [0,0,0,0].pack("N4") + outfile.sysseek outfile.tell scramble(outfile) } end diff --git a/walkgirl/extconf.rb b/walkgirl/extconf.rb new file mode 100644 index 0000000..8395690 --- /dev/null +++ b/walkgirl/extconf.rb @@ -0,0 +1,25 @@ +############################################################################ +# Copyright (C) 2008 by RafaƂ Rzepecki # +# divided.mind@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +require 'mkmf' + +dir_config("nwscrambler") + +create_makefile("nwscrambler") diff --git a/walkgirl/mp3.rb b/walkgirl/mp3.rb index 74f5fa4..613b502 100644 --- a/walkgirl/mp3.rb +++ b/walkgirl/mp3.rb @@ -20,6 +20,7 @@ require 'id3' require 'audiofile' +require 'nwscrambler' module NetworkWalkman class AudioFile @@ -110,7 +111,14 @@ module NetworkWalkman end end @audioStartX, @audioEndX = tags.audioStartX, tags.audioEndX - @tags = tags.tagID3v2 || tags.tagID3v1 + mtags = tags.tagID3v2 || tags.tagID3v1 + @tags = ID3::Tag2.new + mtags.each{|t,v| + begin + @tags[t] = "\3#{v}" + rescue + end + } @tags["ORIGFILENAME"] = "\3#{filename}" self end @@ -122,19 +130,19 @@ module NetworkWalkman save end - def scramble(outfile) - key = 0xFFFFFFFF & (( 0x2465 + @slot * 0x5296E435 ) ^ @dvid); - @file.seek(@audioStartX) - left = @audioEndX - @audioStartX - while left > 0 and block = @file.read([8, left].min) - if block.length != 8 - outfile << block - else - outfile << block.unpack("N2").map{|x|x^key}.pack("N2") - end - left -= block.length - end - end +# def scramble(outfile) +# key = 0xFFFFFFFF & (( 0x2465 + @slot * 0x5296E435 ) ^ @dvid); +# @file.seek(@audioStartX) +# left = @audioEndX - @audioStartX +# while left > 0 and block = @file.read([8, left].min) +# if block.length != 8 +# outfile << block +# else +# outfile << block.unpack("N2").map{|x|x^key}.pack("N2") +# end +# left -= block.length +# end +# end end # class Mp3 diff --git a/walkgirl/nwscrambler.c b/walkgirl/nwscrambler.c new file mode 100644 index 0000000..f8ab50f --- /dev/null +++ b/walkgirl/nwscrambler.c @@ -0,0 +1,66 @@ + +#include + +#include +#include +#include + +static VALUE t_scramble(VALUE self, VALUE outfile) +{ + VALUE file; + unsigned long long key; + unsigned long audioStartX, audioEndX, left; + int in_fd, out_fd; + char buf[8]; + + file = rb_iv_get(self, "@file"); + + audioStartX = FIX2ULONG(rb_iv_get(self, "@audioStartX")); + audioEndX = FIX2ULONG(rb_iv_get(self, "@audioEndX")); + key = 0xFFFFFFFF & (( 0x2465 + FIX2UINT(rb_iv_get(self, "@slot")) * 0x5296E435 ) ^ FIX2UINT(rb_iv_get(self, "@dvid"))); + key = ((key & 0xFF) << 24) | ((key & 0xFF00) << 8) | ((key & 0xFF0000) >> 8) | ((key & 0xFF000000) >> 24); + key = (key << 32) | key; + + rb_funcall(file, rb_intern("sync="), 1, Qtrue); + in_fd = FIX2INT(rb_funcall(file, rb_intern("fileno"), 0)); + + rb_funcall(outfile, rb_intern("sync="), 1, Qtrue); + out_fd = FIX2INT(rb_funcall(outfile, rb_intern("fileno"), 0)); + + lseek(in_fd, audioStartX, SEEK_SET); + left = audioEndX - audioStartX; + while (left > 7 && read(in_fd, buf, 8)) { + *((unsigned long long *) buf) ^= key; + write(out_fd, buf, 8); + left -= 8; + } + + if (left) { + read(in_fd, buf, left); + write(out_fd, buf, left); + } + return Qtrue; +}/* + +def scramble(outfile) + key = 0xFFFFFFFF & (( 0x2465 + @slot * 0x5296E435 ) ^ @dvid); + @file.seek(@audioStartX) + left = @audioEndX - @audioStartX + while left > 0 and block = @file.read([8, left].min) + if block.length != 8 + outfile << block + else + outfile << block.unpack("N2").map{|x|x^key}.pack("N2") + end + left -= block.length + end + end +*/ + +VALUE AudioFile; + +void Init_nwscrambler() +{ + AudioFile = rb_gv_get("NetworkWalkman::Db::AudioFile"); + rb_define_method(AudioFile, "scramble", t_scramble, 1); +} -- 2.11.4.GIT