2008年9月2日火曜日

Cortex M3開発環境 on Mac OS X

Design Wave 2008年5月号STM32基板の開発環境をできるだけ簡単にOS X上に構築する。

(1) クロスコンパイラ
CodeSourceryのGNU Toolchainをコンパイルするのが手っ取り早そうだが,コンパイルすら面倒ということでdevkitARMのOS X版を使うことに。幸いrelease 23bのgccは4.3.0なのでcortex-m3に対応している。

(2) プロジェクトテンプレートの作成
以下の構成のディレクトリを作成する。
$ ls ./gcc_template
FWLib/ USBLib/ ld_script/ src/
Makefile include/ lib/

(3) Firmware Library, USB Library
Design Wave 2008年5月号付属CD-ROM,あるいはSTMicroからダウンロードできるFirmware Library, USB LibraryをFWLib, USBLibディレクトリの下にコピーする。
$ ls -R ./gcc_template/{FWLib,USBLib}
./gcc_template/FWLib:
library/

./gcc_template/FWLib/library:
inc/ src/

./gcc_template/FWLib/library/inc:
cortexm3_macro.h stm32f10x_i2c.h stm32f10x_spi.h
stm32f10x_adc.h stm32f10x_iwdg.h stm32f10x_systick.h
stm32f10x_bkp.h stm32f10x_lib.h stm32f10x_tim.h
stm32f10x_can.h stm32f10x_map.h stm32f10x_tim1.h
stm32f10x_dma.h stm32f10x_nvic.h stm32f10x_type.h
stm32f10x_exti.h stm32f10x_pwr.h stm32f10x_usart.h
stm32f10x_flash.h stm32f10x_rcc.h stm32f10x_wwdg.h
stm32f10x_gpio.h stm32f10x_rtc.h

./gcc_template/FWLib/library/src:
stm32f10x_adc.c stm32f10x_i2c.c stm32f10x_spi.c
stm32f10x_bkp.c stm32f10x_iwdg.c stm32f10x_systick.c
stm32f10x_can.c stm32f10x_lib.c stm32f10x_tim.c
stm32f10x_dma.c stm32f10x_nvic.c stm32f10x_tim1.c
stm32f10x_exti.c stm32f10x_pwr.c stm32f10x_usart.c
stm32f10x_flash.c stm32f10x_rcc.c stm32f10x_wwdg.c
stm32f10x_gpio.c stm32f10x_rtc.c

./gcc_template/USBLib:
library/

./gcc_template/USBLib/library:
inc/ src/

./gcc_template/USBLib/library/inc:
usb_core.h usb_init.h usb_lib.h usb_regs.h
usb_def.h usb_int.h usb_mem.h usb_type.h

./gcc_template/USBLib/library/src:
usb_core.c usb_init.c usb_int.c usb_mem.c usb_regs.c

(4) プログラムスケルトン
付属CD-ROMの「STM32F10xxxのサンプル・プログラムおよびマニュアル/STM32F10xFWLib/FWLib/project」および「STM32F10xxxのサンプル・プログラムおよびマニュアル/STM32F10xFWLib/FWLib/project/RIDE」からプログラムスケルトンとなるソースファイルを./gcc_template/{src,include}にコピーする。
$ ls ./gcc_template/{src,include}
./gcc_template/include:
stm32f10x_conf.h stm32f10x_it.h usb_conf.h

./gcc_template/src:
cortexm3_macro.s stm32f10x_it.c
main.c stm32f10x_vector.c


(5) リンカスクリプト
Design Wave 2008年6月号のJTAGデバッガ自作記事のデータをダウンロードする。ダウンロードしたdata.zipを展開してdata/CQ/ARM_OCD_myJTAG/workspace/LED/ld_scriptにあるリンカスクリプトを./gcc_template/ld_scriptへコピーする。
$ ls ./gcc_template/ld_script
STM32_128K_20K_FLASH.ld STM32_SEC_RAM.ld
STM32_COMMON.ld STM32_SEC_RAMonly.ld
STM32_SEC_EXT.ld stm32.ld
STM32_SEC_FLASH.ld

また,DFU領域を書き潰さないようにstm32.ldを以下のように修正しておく。
9c9
< INCLUDE "./ld_script/STM32_COMMON.ld"
---
> INCLUDE "../ld_script/STM32_COMMON.ld"
15,16c15,16
< /* FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K */
> FLASH (rx) : ORIGIN = 0x8003000, LENGTH = 128K - 12K
---
< FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
> /*FLASH (rx) : ORIGIN = 0x8003000, LENGTH = 128K - 12K */
29c29
< INCLUDE "./ld_script/STM32_SEC_FLASH.ld"
---
> INCLUDE "../ld_script/STM32_SEC_FLASH.ld"


(6) Thum2ライブラリ
data/CQ/ARM_OCD_myJTAG/workspace/LED/lib_thumb2にあるThumb2でコンパイルされたライブラリを./gcc_template/libへコピーする。
$ ls ./gcc_template/lib
libc.a libgcc.a libiberty.a
libg.a libgcov.a libm.a

また,data/CQ/ARM_OCD_myJTAG/workspace/LED/src/syscalls.cを./gcc_template/srcへコピーしておく。

(7) Makefile
以下の内容でmakefileを作成する。
###
### Makefile for STM32F10x Cortex-M3
###

PROG = target

SRCDIR = ./src
CFILES = ${SRCDIR}/main.c \
${SRCDIR}/stm32f10x_vector.c \
${SRCDIR}/stm32f10x_it.c
SFILES = ${SRCDIR}/cortexm3_macro.s

CC = arm-eabi-gcc
AS = arm-eabi-as
AR = arm-eabi-ar
LD = arm-eabi-ld
OBJCOPY = arm-eabi-objcopy

CFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g -O2
ASFLAGS = -mthumb
LDFLAGS = --cref -gc-sections -Map=${PROG}.map -T ld_script/stm32.ld -L ./lib

INCLUDES = -I./include -I./FWLib/library/inc -I./USBLib/library/inc

# Firmware Library source files
FWLIBDIR = ./FWLib/library/src
FWLIBFILES = \
${FWLIBDIR}/stm32f10x_adc.c\
${FWLIBDIR}/stm32f10x_bkp.c\
${FWLIBDIR}/stm32f10x_can.c\
${FWLIBDIR}/stm32f10x_dma.c\
${FWLIBDIR}/stm32f10x_exti.c\
${FWLIBDIR}/stm32f10x_flash.c\
${FWLIBDIR}/stm32f10x_gpio.c\
${FWLIBDIR}/stm32f10x_i2c.c\
${FWLIBDIR}/stm32f10x_iwdg.c\
${FWLIBDIR}/stm32f10x_lib.c\
${FWLIBDIR}/stm32f10x_nvic.c\
${FWLIBDIR}/stm32f10x_pwr.c\
${FWLIBDIR}/stm32f10x_rcc.c\
${FWLIBDIR}/stm32f10x_rtc.c\
${FWLIBDIR}/stm32f10x_spi.c\
${FWLIBDIR}/stm32f10x_systick.c\
${FWLIBDIR}/stm32f10x_tim.c\
${FWLIBDIR}/stm32f10x_tim1.c\
${FWLIBDIR}/stm32f10x_usart.c\
${FWLIBDIR}/stm32f10x_wwdg.c

# USB Library source files
USBLIBDIR = ./USBLib/library/src
USBLIBFILES = \
${USBLIBDIR}/usb_core.c\
${USBLIBDIR}/usb_init.c\
${USBLIBDIR}/usb_int.c\
${USBLIBDIR}/usb_mem.c\
${USBLIBDIR}/usb_regs.c

OBJS = ${CFILES:.c=.o} ${SFILES:.s=.o}
LIBOBJS = ${FWLIBFILES:.c=.o} ${USBLIBFILES:.c=.o}

.SUFFIXES: .c .s .o

.c.o:
${CC} ${CFLAGS} ${INCLUDES} -c $< -o $@

.s.o:
${AS} ${ASFLAGS} $< -o $@

all: ${PROG}.s19

./lib/libstm32.a : ${LIBOBJS}
${AR} cr $@ ${LIBOBJS}

${PROG}.elf : ${OBJS} ./lib/libstm32.a
${LD} ${LDFLAGS} ${OBJS} -lstm32 -o $@

${PROG}.s19: ${PROG}.elf
$(OBJCOPY) -O srec ${PROG}.elf ${PROG}.s19

${PROG}.hex: ${PROG}.elf
$(OBJCOPY) -O ihex ${PROG}.elf ${PROG}.hex

clean :
rm -rf ${OBJS} ${LIBOBJS} ${PROG}.elf ${PROG}.s19 ${PROG}.hex ${PROG}.map ./lib/libstm32.a

2008年5月8日木曜日

gpSP 改のインストール

GBAエミュレータgpSP改をPSPへインストールしてみたので手順をメモ。

GBA BIOSの吸い出し
まず,GBA本体からBIOSを吸い出す。吸い出しに必要な
  1. USBケーブル (Flash2AdvanceのUSB Linkerを使用)
  2. FlashManager for GBA
  3. FM3_Debug - BIOS吸い出しプログラム
を用意。吸い出し手順は以下の通り。
  1. FlashManagerを起動してGBAとリンクさせる
  2. GBAデバッグモードにする
  3. デバッグモードで「実行」ボタンを押すとプログラム選択画面となるのでFM3_Debug.binを選択
  4. [A+START]ボタンでBIOS吸い出しを開始
  5. 吸い出されたBIOSイメージはbios.binに保存される
gpSPのインストール
吸い出したBIOSイメージとゲームのROMイメージを用意してPSPのメモリースティックに必要なファイルをコピーする。
  1. gpSP改のページからgpsp.zipを入手,展開。
  2. BIOSイメージを./gpsp/gba_bios.binの名前で置く。
  3. GBA ROMファイル xxx.gba を ./gpsp/GBA/ROM/xxx.gbaに置く。saveファイルがあれば ./gpsp/GBA/SAV/xxx.savに。
  4. gpsp以下をCustomFirmware化されたPSPのms0:/PSP/GAME150/gpspへコピー。

2008年4月16日水曜日

build gcc for ARM

(1) gccのコンパイルの前に,codesourceryからダウンロードしたARM GNU/Linux の バイナリを展開し,ターゲット用のヘッダとライブラリ一式をホスト環境へコピーしておく。
$ bunzip2 -c arm-2008q1-126-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 | tar xvf -
$ cd arm-2008q1
$ sudo cp -r arm-none-linux-gnueabi/libc /opt/codesourcery/arm-none-linux-gnueabi/libc

(2) gccのソースファイルを展開する。
$ bunzip2 -c gcc-2008q1-126.tar.bz2 | tar xf -

(3) binutilsの場合と同様に,pdf をインストールしないようあらかじめMakefile.inを修正しておく。
*** gcc-4.2/Makefile.in 2008-04-17 01:22:09.000000000 +0900
--- gcc-4.2/Makefile.in.orig 2008-04-17 01:21:51.000000000 +0900
***************
*** 2352,2358 ****
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(MAKE) $(RECURSE_FLAGS_TO_PASS) installdirs \
! install-host install-target install-html

.PHONY: install-host-nogcc
install-host-nogcc: \
--- 2352,2358 ----
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(MAKE) $(RECURSE_FLAGS_TO_PASS) installdirs \
! install-host install-target install-html install-pdf

.PHONY: install-host-nogcc
install-host-nogcc: \

*** gcc-4.2/gcc/Makefile.in 2008-04-17 01:22:48.000000000 +0900
--- gcc-4.2/gcc/Makefile.in.orig 2008-04-17 01:22:25.000000000 +0900
***************
*** 3779,3785 ****
# Install the driver last so that the window when things are
# broken is small.
install: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \
! install-cpp install-man install-info install-html \
install-@POSUB@ install-driver

# Handle cpp installation.
--- 3779,3785 ----
# Install the driver last so that the window when things are
# broken is small.
install: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \
! install-cpp install-man install-info install-html install-pdf \
install-@POSUB@ install-driver

# Handle cpp installation.

(4) arm-2008q1-126-arm-none-linux-gnueabi.sh のbuild手順を参考に arm 用の gcc をコンパイルする。
$ mkdir -p BUILD/gcc-final
$ pushd BUILD/gcc-final
$ export AR_FOR_TARGET=arm-none-linux-gnueabi-ar
$ export NM_FOR_TARGET=arm-none-linux-gnueabi-nm
$ export OBJDUMP_FOR_TARGET=arm-none-linux-gnueabi-objdump
$ export STRIP_FOR_TARGET=arm-none-linux-gnueabi-strip
$ export PATH=/opt/codesourcery/bin:${PATH}
$ ../../gcc-4.2/configure \
--build=i686-apple-darwin9 --host=i686-apple-darwin9 \
--target=arm-none-linux-gnueabi --enable-threads --disable-libmudflap --disable-libssp \
--disable-libgomp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --enable-languages=c,c++ \
--enable-shared --enable-symvers=gnu --enable-__cxa_atexit --disable-nls \
--prefix=/opt/codesourcery \
--with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc \
--with-build-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc \
--enable-poison-system-directories \
--with-build-time-tools=/opt/codesourcery/arm-none-linux-gnueabi/bin \
--with-build-time-tools=/opt/codesourcery/arm-none-linux-gnueabi/bin 2>&1 |tee configure.out
$ sudo make -j4 LDFLAGS_FOR_TARGET=--sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc \
CPPFLAGS_FOR_TARGET=--sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc \
build_tooldir=/opt/codesourcery/arm-none-linux-gnueabi 2>&1 | tee make.out
$ make prefix=/opt/codesourcery exec_prefix=/opt/codesourcery \
libdir=/opt/codesourcery/lib \
htmldir=/opt/codesourcery/share/doc/arm-arm-none-linux-gnueabi/html \
pdfdir=/opt/codesourcery/share/doc/arm-arm-none-linux-gnueabi/pdf \
infodir=/opt/codesourcery/share/doc/arm-arm-none-linux-gnueabi/info \
mandir=/opt/codesourcery/share/doc/arm-arm-none-linux-gnueabi/man \
install 2>&1 |tee make_install.out
$ popd

これで /opt/codesourcery 以下にARM Linux用のクロスコンパイラ一式が整った。

2008年4月8日火曜日

build binutils for ARM

(1) CodeSourceryからダウンロードしたarm-2008q1-126-arm-none-linux-gnueabi.src.tar.bz2を展開するとarm-2008q1-126-arm-none-linux-gnueabi以下にtoolchainの各ソースコードが展開されるので,まずbinutilsをコンパイルする。binutils-2008q1-126.tar.bz2を展開するとディレクトリbinutils-stable以下にソースが展開される。
$ bunzip2 -c arm-2008q1-126-arm-none-linux-gnueabi.src.tar.bz2 | tar xf -
$ cd arm-2008q1-126-arm-none-linux-gnueabi
$ bunzip2 -c binutils-2008q1-126.tar.bz2 | tar xf -

(2) TeXがないとインストール時にエラーが発生するので,あらかじめ pdf をインストールしないようMakefile.inを修正しておく。

*** binutils-stable/Makefile.in 2008-04-17 01:06:54.000000000 +0900
--- binutils-stable/Makefile.in.orig 2008-04-17 01:06:13.000000000 +0900
***************
*** 2471,2477 ****
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(MAKE) $(RECURSE_FLAGS_TO_PASS) installdirs \
! install-host install-target install-html

.PHONY: install-host-nogcc
install-host-nogcc: \
--- 2471,2477 ----
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(MAKE) $(RECURSE_FLAGS_TO_PASS) installdirs \
! install-host install-target install-html install-pdf

.PHONY: install-host-nogcc
install-host-nogcc: \

(3) arm-2008q1-126-arm-none-linux-gnueabi.sh のbuild手順を参考に arm 用の binutils をコンパイルする。
$ mkdir -p ./BUILD/binutils
$ pushd BUILD/binutils
$ ../../binutils-stable/configure \
--build=i686-apple-darwin9 --target=arm-none-linux-gnueabi \
--prefix=/opt/codesourcery --host=i686-apple-darwin9 \
--disable-nls --with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc \
--enable-poison-system-directories 2>&1 | tee configure.out
$ make -j4 2>&1 | tee make.out
$ sudo make install \
prefix=/opt/codesourcery exec_prefix=/opt/codesourcery \
libdir=/opt/codesourcery/lib \
htmldir=/opt/codesourcery/share/doc/arm-arm-none-linux-gnueabi/html \
pdfdir=/opt/codesourcery/share/doc/arm-arm-none-linux-gnueabi/pdf \
infodir=/opt/codesourcery/share/doc/arm-arm-none-linux-gnueabi/info \
mandir=/opt/codesourcery/share/doc/arm-arm-none-linux-gnueabi/man \
datadir=/opt/codesourcery/share 2>&1 |tee make_install.out
$ popd

※ 手順を2008Q1リリース版に合わせる(2008年4月17日)

2008年4月7日月曜日

GNU Toolchain for ARM

androidはじめました」ということで,まずはARMのクロスコンパイラをOS X上に準備。CodeSourceryから提供されるGNU Toolchainをベースに環境を構築することにして
  • Target: ARM GNU/Linux,Host: IA32 GNU/Linuxのバイナリ
  • Target: ARM GNU/Linuxのソース
をダウンロード。

2008年4月4日金曜日

iTunesのプレイリストをSO905iへ

m4aファイルに3gpメタデータを埋め込むことができたので,iTunesのプレイリストからmicroSDカードへのAACファイルの書き込み,メタデータ埋め込みを自動化してみる。iTunesのプレイリストに登録された曲の取得にはScriptingBridgeを使う。
(1) iTunesのプレイリスト"SO905i"からScriptingBridgeを通してtrack一覧を取得,(2) 各ファイルの拡張子を.m4aから.3gpに変えながらmicroSDにコピー,(3)3gpメタデータを埋め込む,という手順でrubyスクリプトを作ってみた。

#!/usr/bin/env ruby

# configuration
LIB_NAME = 'ライブラリ'
PLAYLIST_NAME = 'SO905i'
DEST_DIR = '/Volume/Untitled/MUSIC'
ITUNES_BASE = '/Users/nishio/Music/iTunes/iTunes Music/'
CMD_M4A = '/Users/nishio/bin/AtomicParsley'
CMD_3GP = '/Users/nishio/bin/AtomicParsley_3gp'

# load libraries
require 'fileutils'
require 'pathname'
require 'osx/cocoa' # load cocoa library.
include OSX # setup for scripting bridge.
OSX.require_framework 'ScriptingBridge'

###
### convert m4a metadata to 3gp metadata
###
def m4a_to_3gp(file)
file = file.gsub(/"/) {|s| '\\' + s} # escape double quote
# parse .m4a atom
h = Hash.new
open("| #{CMD_M4A} \"#{file}\" -t") { |f|
while line = f.gets
line =~ /Atom "(.*)".* contains: (.*)/
h[$1] = $2.gsub(/"/) {|s| '\\' + s} # escape double quote
end
}

# put .3gp atom
h["trkn"] =~ /([0-9]*) of [0-9]*/
num = $1
args = "--3gp-title \"#{h["\302\251nam"]}\" lang=jpn --3gp-performer \"#{h["\302\251ART"]}\" lang=jpn --3gp-album \"#{h["\302\251alb"]}\" track=#{num} lang=jpn --3gp-genre \"#{h["\302\251gen"]}\" lang=jpn --3gp-year '#{h["\302\251day"]}' --overWrite"
system("#{CMD_3GP} \"#{file}\" #{args}")
end

######################################################################
# main routine begins here.

iTunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
iTunes.sources.each do |source|
next unless source.name == LIB_NAME
source.userPlaylists.each do |playlist|
next unless playlist.name == PLAYLIST_NAME
base = Pathname.new(ITUNES_BASE)
playlist.fileTracks.each do |track|
next unless track.enabled?

path = track.location.path
path_name = Pathname.new(path)
ext_name = File.extname(path)
dst_name = DEST_DIR + path_name.relative_path_from(base)
dst_dir = File.dirname(dst_name)

# create destination directories if not exists.
if !FileTest.exist?(dst_dir) then
puts "make directory: #{dst_dir}"
FileUtils.mkdir_p(dst_dir)
end

# copy a file
puts "copy file: #{dst_name}"
case ext_name
when '.m4a' then
dst_name = File.join(dst_dir, File.basename(dst_name, ext_name) + '.3gp')
FileUtils.cp(path, dst_name)
m4a_to_3gp(dst_name)
else
FileUtils.cp(path, dst_name)
end
end
end
end

2008年3月28日金曜日

m4aから3gpへのメタデータ変換

iTunesで作成したAACファイル(.m4a)のメタデータをAtomicParsleyで表示してみる。
$ ~/bin/AtomicParsley 16\ 後出し.m4a -t
Atom "©nam" contains: 後出し
Atom "©ART" contains: ケツメイシ
Atom "©wrt" contains: ケツメイシ
Atom "©alb" contains: ケツノポリス2
Atom "©gen" contains: Hip Hop/Rap
Atom "trkn" contains: 16 of 16
Atom "disk" contains: 1 of 1
Atom "©day" contains: 2002
Atom "cpil" contains: false
Atom "tmpo" contains: 0


PS3で作成した AAC ファイル(.3gp)のメタデータをAtomicParsleyで表示してみると
$ ~/bin/AtomicParsley_3gp スタート.3gp -t
User data "titl" [lang=jpn (utf16)] : スタート
User data "perf" [lang=jpn (utf16)] : ケツメイシ
User data "gnre" [lang=jpn (utf16)] : Rock
User data "albm" [lang=jpn (utf16)] : ケツノポリス5 | Track: 1
User data "yrrc" : 2007

なので'©nam'を'titl','©ART'を'perf',’©alb'を'albm','©gen'を'gnre'に書き込めばよい。

AtomicParsleyとrubyで変換スクリプトをquick hack。

#!/usr/bin/env ruby

# config
CMD_M4A = '/Users/nishio/bin/AtomicParsley'
CMD_3GP = '/Users/nishio/bin/AtomicParsley_3gp'

# convert m4a metadata to 3gp metadata
def m4a_to_3gp(file)
file = file.gsub(/"/) {|s| '\\' + s} # escape double quote
# parse .m4a atom
h = Hash.new
open("| #{CMD_M4A} \"#{file}\" -t") { |f|
while line = f.gets
line =~ /Atom "(.*)".* contains: (.*)/
h[$1] = $2.gsub(/"/) {|s| '\\' + s} # escape double quote
end
}

# put .3gp atom
h["trkn"] =~ /([0-9]*) of [0-9]*/
num = $1
args = "--3gp-title \"#{h["\302\251nam"]}\" lang=jpn --3gp-performer \"#{h["\302\251ART"]}\" lang=jpn --3gp-album \"#{h["\302\251alb"]}\" track=#{num} lang=jpn --3gp-genre \"#{h["\302\251gen"]}\" lang=jpn --3gp-year '#{h["\302\251day"]}' --overWrite"
system("#{CMD_3GP} \"#{file}\" #{args}")
end

# main begins.
file = ARGV[0]
m4a_to_3gp(file)

3gpメタデータの書き込み

SO905iでも正しく表示が行われるPS3で作成した AAC ファイル(.3gp)のメタデータをAtomicParsleyで表示してみると
$ ~/bin/AtomicParsley スタート.3gp -t
User data "titl" [lang=jpn (utf16)] : スタート
User data "perf" [lang=jpn (utf16)] : ケツメイシ
User data "gnre" [lang=jpn (utf16)] : Rock
User data "albm" [lang=jpn (utf16)] : ケツノポリス5 | Track: 1
User data "yrrc" : 2007


なので,iTunesで作られたAACファイルにAtomicParsleyを使って'titl', 'perf', 'albm', 'gnre'を書き込んでやればSO905i上でも曲データが表示されるようになると思われる。試しにalbmを書き込んでみると……
$ ~/bin/AtomicParsley 16\ 後出し.m4a --3gp-album "Test Album" lang=jpn
AtomicParsley warning:
the 'albm' tag is only allowed on files of '3gp6' brand & later.
Skipping.
No changes.


どうやらAtomicParsleyは 'ftyp' atom の majorBrand の値を見てメタデータ形式を決定しているようなので,iTunes で作成した AAC ファイルに 3gp6 のtag を(無理やり)書き込めるよう AtomicParsleyを修正してみた。iTunes で作成したAACファイルのmajorBrandは'M4A ',PS3で作成したAACのmajorBrandは'3gp6'なので,AtomicParsley.cpp内部で'M4A 'を'3gp6'と同様に扱うよう修正。
*** AtomicParsley.cpp.orig 2008-03-28 01:42:33.000000000 +0900
--- AtomicParsley.cpp 2008-03-28 01:43:56.000000000 +0900
***************
*** 2114,2119 ****
--- 2114,2120 ----
metadata_style = THIRD_GEN_PARTNER;
break;

+ case 0x4D344120 : //'M4A ' -- these are all listed at http://www.mp4ra.org/filetype.html as registered brands
case 0x33677036 : //'3gp6'

case 0x33677236 : //'3gr6' progressive
***************
*** 2129,2135 ****
metadata_style = ITUNES_STYLE;
psp_brand = true;
break;
! case 0x4D344120 : //'M4A ' -- these are all listed at http://www.mp4ra.org/filetype.html as registered brands
case 0x4D344220 : //'M4B '
case 0x4D345020 : //'M4P '
case 0x4D345620 : //'M4V '
--- 2130,2136 ----
metadata_style = ITUNES_STYLE;
psp_brand = true;
break;
! //case 0x4D344120 : //'M4A ' -- these are all listed at http://www.mp4ra.org/filetype.html as registered brands
case 0x4D344220 : //'M4B '
case 0x4D345020 : //'M4P '
case 0x4D345620 : //'M4V '


修正した実行ファイル(AtomicParsley_3gp)でもう一度 albm を書き込んでみると
$ ~/bin/AtomicParsley_3gp 16\ 後出し.m4a --3gp-album "Test Album" lang=jpn --overWrite
......
Finished writing to temp file.
$ ~/bin/AtomicParsley_3gp 16\ 後出し.m4a -t
User data "albm" [lang=jpn (utf8)] : Test Album


m4aファイルに3gpのメタデータを追記できた。

2008年3月27日木曜日

m4a と 3gp のメタデータ

iTunesで作成した AAC ファイルを SO905i に持っていくと曲メタデータが「不明」となってしまう。これではあまりに不便なので変換する方法を調べてみる。

MP3 であれば id3 でメタデータが格納されているが,iTunes の AAC ファイルのメタデータは独自のatomに格納しているようだ。
AtomicParsleyを使えば iTunes 形式と 3GPP 形式のメタデータの編集ができそう。
AtomicParsley is a lightweight command line program for reading, parsing and setting metadata into MPEG-4 files supporting these styles of metadata:

iTunes-style metadata into .mp4, .m4a, .m4p, .m4v, .m4b files
3gp-style assets (3GPP TS 26.444 version 6.4.0 Release 6 specification conforming) in 3GPP, 3GPP2, MobileMP4 & derivatives
ISO copyright notices at movie & track level for MPEG-4 & derivative files
uuid private user extension text & file embedding for MPEG-4 & derivative files