音声

音声を取り扱うにあたってのメモ
AndroidManifest.xml

<uses-permission android:name="android.permission.RECORD_AUDIO" /> 

録音に使用したもの

コンストラクタ
AudioRecord
メソッド
AudioRecord.getMinBufferSize
AudioRecord.setNotificationMarkerPosition
AudioRecord.setPositionNotificationPeriod
AudioRecord.setRecordPositionUpdateListener
AudioRecord.startRecording
AudioRecord.read
AudioRecord.stop
AudioRecord.release

AudioRecord
再生に使用したもの

コンストラクタ
AudioTrack
メソッド
AudioTrack.getMinBufferSize
AudioTrack.play
AudioTrack.write
AudioTrack.stop
AudioTrack.release

AudioTrack

Key-Value Coding

・Key-Value Coding略してKVCなるものがあるということやってみた。
ソース

#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>

@interface MyClass:NSObject
@property(copy) NSString *name;
@end

@implementation MyClass
@synthesize name;
@end

int main () {
	id pool = [[NSAutoreleasePool alloc] init];
	id obj = [[MyClass alloc] init];
	[obj setValue:@"hello world" forKey:@"name"];
	NSLog(@"%@", [obj valueForKey:@"name"]);
	return 0;
}

コンパイルと結果

gcc -c -I/usr/include/GNUstep -fconstant-string-class=NSConstantString main.m
main.m:45:1: エラー: ivar ‘name’ used by ‘@synthesize’ declaration must be an existing ivar
main.m:46:1: 警告: incomplete implementation of class ‘MyClass’ [デフォルトで有効]
main.m:46:1: 警告: method definition for ‘-setName:’ not found [デフォルトで有効]
main.m:46:1: 警告: method definition for ‘-name’ not found [デフォルトで有効]
main.m: 関数 ‘main’ 内:
main.m:51:2: 警告: no ‘-setValue:forKey:’ method found [デフォルトで有効]
main.m:51:2: 警告: (Messages without a matching method signature [デフォルトで有効]
main.m:51:2: 警告: will be assumed to return ‘id’ and accept [デフォルトで有効]
main.m:51:2: 警告: ‘...’ as arguments.) [デフォルトで有効]
main.m:52:2: 警告: no ‘-valueForKey:’ method found [デフォルトで有効]
make: *** [main.o] エラー 1

・「ivar ‘name’ used by ‘@synthesize’ declaration must be an existing ivar」とあるので
ソース修正

#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>

@interface MyClass:NSObject
{
	NSString *name;
}
@property(copy) NSString *name;
@end

@implementation MyClass
@synthesize name;
@end

int main () {
	id pool = [[NSAutoreleasePool alloc] init];
	id obj = [[MyClass alloc] init];
	[obj setValue:@"hello world" forKey:@"name"];
	NSLog(@"%@", [obj valueForKey:@"name"]);
	return 0;
}

コンパイルと結果

gcc -c -I/usr/include/GNUstep -fconstant-string-class=NSConstantString main.m
main.m: 関数 ‘main’ 内:
main.m:51:2: 警告: no ‘-setValue:forKey:’ method found [デフォルトで有効]
main.m:51:2: 警告: (Messages without a matching method signature [デフォルトで有効]
main.m:51:2: 警告: will be assumed to return ‘id’ and accept [デフォルトで有効]
main.m:51:2: 警告: ‘...’ as arguments.) [デフォルトで有効]
main.m:52:2: 警告: no ‘-valueForKey:’ method found [デフォルトで有効]
gcc -I/usr/include/GNUstep -fconstant-string-class=NSConstantString -o test main.o -lgnustep-base

警告が気になりつつもコンパイルできた。
内容は、methodが無いよ?ということだろうか?
@synthesizeがやってくれているものだと思うのだけど

・とりあえず実行してみる
実行結果

2012-12-27 17:36:24.903 test[6730] hello world

・便利である。

makefile作ってみる

TARGET = test

CC       = gcc
INCLUDES = -I/usr/include/GNUstep
CFLAGS   = -fconstant-string-class=NSConstantString
LIBS     = -lgnustep-base 

SRCS := $(wildcard *.m)
OBJS := $(SRCS:%.m=%.o)

$(TARGET):$(OBJS)
	$(CC) $(INCLUDES) $(CFLAGS) -o $@ $^ $(LIBS)

clean:
	@rm -f $(TARGET)
	@rm -f $(OBJS)

.SUFFIXES:.m .o
.m.o:
	$(CC) -c $(INCLUDES) $(CFLAGS) $^

Objective-Cに触れてみる

Objective-Cに必要なものをaptしてみる。
aptメモ

gobjc
gobjc-multilib

Objective-Cのソースをみてみる。

#import
@interface
@implementation
@end
[]
id

見慣れる単語に戸惑う。

・とりあえずソースを写経してみる。
単語@implementationに戸惑う。
インプリメンテーションインプリメンテーションインプリメンテーション…

コンパイルしてみる。

gcc -C main.m
致命的エラー: Foundation/NSObject.h: そのようなファイルやディレクトリはありません

・問題を検索する。
以下をaptすればよいようだ。
aptメモ

autotools-dev
gnustep-base-common
gnustep-base-runtime
gnustep-common
gnustep-make
libgnustep-base-dev
libgnustep-base1.22

GNUstep wiki

・再度コンパイルしてみる。

gcc -C main.m -I/usr/include/GNUstep
エラー: cannot find interface declaration for ‘NXConstantString’

写経したソース内で「@"文字列"」を使うとエラーが出るみたいだよ

文字列定数クラスとは何ですか

@"Hello world!"のようなObjective-Cの文字列リテラルを 使用する場合、その文字列オブジェクトのクラスは通常NXConstantString になります。この文字列クラスは、コンパイル時に gccの-fconstant-string-classオプションを使用して変更することが できます。Cocoaでは、文字列リテラルのクラスはNSConstantStringに なります。もし、文字列定数クラスを別のものに変更したいなら、そのクラスには どのようなメソッドを実装してもよいですが、インスタンス変数のレイアウトは、 メモリ上のレイアウトをコンパイラが実行ファイルに書き込むので、 N[SX]ConstantStringと同じにしなければなりません (objc/NXConstStr.h、または、Foundation/NSString.hを参照)。

文字列定数クラスとは何ですか

・再々度コンパイル

gcc -C main.m -I/usr/include/GNUstep -fconstant-string-class=NSConstantString
main.m:(.text+0x12): undefined reference to `objc_get_class'
main.m:(.text+0x24): undefined reference to `objc_msg_lookup'
main.m:(.text+0x43): undefined reference to `objc_msg_lookup'
main.m:(.text+0x60): undefined reference to `objc_get_class'
main.m:(.text+0x72): undefined reference to `objc_msg_lookup'
main.m:(.text+0x91): undefined reference to `objc_msg_lookup'
main.m:(.text+0xb6): undefined reference to `objc_msg_lookup'
main.m:(.text+0xdf): undefined reference to `objc_msg_lookup'
main.m:(.text+0x108): undefined reference to `objc_msg_lookup'
/tmp/ccmAwX03.o: In function `__objc_gnu_init':
main.m:(.text+0x131): undefined reference to `__objc_exec_class'
/tmp/ccmAwX03.o:(.data+0x70): undefined reference to `__objc_class_name_Song'
/tmp/ccmAwX03.o:(.data+0x74): undefined reference to `__objc_class_name_Singer'
/tmp/ccmAwX03.o:(.data+0x78): undefined reference to `__objc_class_name_NSConstantString'
collect2: ld はステータス 1 で終了しました

・4度目コンパイル
リンクオプションをつける。

gcc -C main.m -I/usr/include/GNUstep -fconstant-string-class=NSConstantString -lgnustep-base

・実行してみる。

./a.out 
2012-12-26 17:20:00.189 a.out[9832] autorelease called without pool for object (0x9bf2790) of class GSAutoreleasedMemory in thread <NSThread: 0x9bc2498>

・ソースを編集する。
以下を追記することによりメッセージがでなくなった。
詳しいことはあとあと調べよう。

#import <Foundation/NSAutoreleasePool.h>
…
id pool = [[NSAutoreleasePool alloc] init];

・スタートラインに立つ
ここからやっとこさObjective-Cに触れて行けそうである。

grub

/etc/default/grubに以下を追加
GRUB_DISABLE_OS_PROBER=true

‘GRUB_DISABLE_OS_PROBER’
Normally, grub-mkconfig will try to use the external os-prober program, if installed, to discover other operating systems installed on the same system and generate appropriate menu entries for them. Set this option to ‘true’ to disable this.