2011/11/24

Template for Jenkins Jobs for PHP Projects にJenkins を PHP で利用する方法が紹介されています。

プラグインのインストール

コマンドでインストールした方が確実かな?とは思いましたが、ブラウザでもできるので[Jenkinsの管理]からインストールしてみました。 Jenkins

php-template のダウンロード

Jenkins の再起動はとりあえず launchctl を使いまいしたが、ブラウザにある[Jenkins管理]>[設定の再読み込み]で良かったみたいです(多分)。

ちなみにコマンドラインは、ブラウザの[Jenkins管理]>[Jenkins CLI]にマニュアルがありますが、これを見る限り、safe-restart で良いのかな?

ともあれ、php-template が読み込まれました。 Jenkins

ジョブの作成

[新規ジョブ作成] からジョブを作成するが、今回は「既存のコピー」に 「php-template」を入力して使う。 Jenkins

PHPUnit のインストール

実は開発でPear は全く使ってなかったので、今更ながらインストールしようと思ったら、Macports で php5-unit なるパッケージを発見したのでインストールしてみる。

sudo port install php5-unit

  2011/11/23

storyboardの詳細は、WWDC2011 セッションを参照

今回の資料

20111123STiDEV.pdf (UISctoryboard *)instantiateInitialViewController

UIStroyboardSegue

Push, Modal, Custom がある

大ざっと調べたところ、 Push は UINavigationController で利用、Modal は通常の画面遷移、Custom は カスタムクラスを作成して拡張、と言う感じに使い分けるようです。

Segueの呼び出し

(1) Storyboardだけで利用:prepareForSegue (2) プログラム上で利用:performSegueWithIdentifier

prepareForSegue:sender:

  • 呼び出しもとcontroller が呼ばれる
  • sender で状況判断
  • segue

実際に確認しましたが、prepareForSegue は Storyboard で UIButton 等からDrag & Drop で Segue を作成し、トリガー時に呼ばれます(delegateメソッド)。 簡単に言えば、画面遷移だけなら prepareForSegue は使わずにノンプログラムで可能です。 Segue ただし次の画面にデータを受け渡す場合は、prepareForSegue を利用します。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showDetailSegue"]) {
        DetailViewController *viewController = (DetailViewController *)[segue destinationViewController];
        viewController.hoge = _hoge;
    }
}

この場合ポイントは、

<

p class="code>Segue の identifier 判別 destinationViewController による UIViewController の取得

です。 まだ勉強したてなのであれですが、欠点としては Segue が増えた場合の管理が大変そうです。 Segue が存在しない場合に、try catch による Exceptionエラーは勿論、複数画面による条件処理ですね。

performSegueWithIdentifier:sender:

  • プログラムから遷移する場合に利用
  • ボタンを作らない場合
  • TableView を使う場合

実際に確認しましたが、performSegueWithIdentifier は、Styoryboard 上に Identifire 付きで Segue を作成し、プログラム上で明示的に Segue を呼び出す方法です。 プログラム上で UI を作成する場合に利用するかと思います。

[self performSegueWithIdentifier:@"Segue の Identifier" sender:self];

もっと言うと、sender:self の為、そのクラス内の prepareForSegue が呼ばれます。

iOS4 までは initWithNibName して addSubView なり presentModalViewController なりして画面遷移していたが、Storyboard と Segue を利用すれば、Storyboard で一括管理でき、上記の1行だけで画面遷移できる事でしょうか?

CustomSegue

storyboard

Storyboard Segue で Style = Custom 、Segue Class に Segue クラスを設定 storyboard initWithIdentifire:source

RelationShip

内容を別のシーン定義に - Navigation - TabBar

問題点

  • 適切な、Segue がないとException ※try catch で対処
  • コードに Segue を書くとダサい

Facebook や GMail っぽい UI

  • ViewController コンテナ 親View 子Viewの切り替えを1つの View コントローラーで実現する。

  • WWDC2011 Session 102 'Impleenting UIViewController Containment"

  • GitHub
  • 参考アプリ

didMoveToParentViewController: で切り替え - toViewが上面に来てしまう - 置換が目的で、元に戻す手順が無い - viewController の view階層は自分で管理し、open/close を自分で書く必要がある。 - addSubView でなく insertSubView を利用

Static Cells TableView

固定のテーブルビューが作成可能 - delegateメソッドを未定義にしておく - UITableView はカスタムできない

Sceneパレット

  • view階層の外に置いてプログラムから利用するIBOutletを定義

User Defined Runtime Attributes

実行時に値を指定できる - KVO を利用している - Key Path でデータを設定

  2011/11/23

CI(継続的インテグレーション)ツールJenkins 何とも親切に OSX のインストーラまでついてます。

が、デフォルトだとアクセス権の問題で正常に起動できないようです。 Jenkins Mac OS X InstallerでJenkinsを入れる を参考に設定しました。

設定ファイルを確認

/Library/LaunchDaemons/org.jenkins-ci.plist

このファイルに、Jenkins のウェブルート(JENKINS_HOME )が設定されている。


        
                JENKINS_HOME
                /Users/Shared/Jenkins/Home
        

普通にインストール数と共有ディレクトリが指定されるが、Home ディレクトリが作成されない。

/Users/Shared/Jenkins

手動で Home ディレクトリを作成

$ cd /Users/Shared/Jenkins/ $ sudo chown daemon /Users/Shared/Jenkins/Home/ $ sudo chgrp daemon Home

デーモン再読起動

$ sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist $ sudo launchctl load /Library/LaunchDaemons/org.jenkins-ci.plist

http://localhost:8080/ にアクセスすると Jenkins が表示される。 Jenkins

ちなみに、Jenkins を Xcode4 の UnitTest する動画があります。

  2011/11/23

サンプルソース

NSDefault からユーザ名、パスワードが盗まれる可能性

キーチェーンに登録

UIKeyChainString を利用する

[UIKeyChainString setString: @"xxxxx" forKey:@"username"];

//サービス(ドメイン)名を指定
[UIKeyChainString setString:@"xxxxx" forKey:@"username" service: @"com.xxxxx"];

//インスタンスを利用
UIKeyChainString *store = [UIKeyChainString keyChainStoreWith];

[store removeItemForKey: @"username"];
[store synchronize]; //Write to keychain

miil のつくりかた

背景やナビゲーションを画面ごとに効率よく変える

- void drawInRect:(CGRect) rect {
    [background drawAsPatternInRect: rect];
}

■UITableView のパフォーマンス - FFTimelineTitleCell - FFTimelineMoreCommentCell など、セルのカスタマイズが多い

全体の処理時間より、イベントループごとの時間を短くする事で体感的に早い場合が多い。

セルの単位を細かくしてやる

画像の表示 - UIImageView ○ - CALayer ○ - UIImage drawRect △

※最適化 png をすると drawRect が一番早い

■画面のキャッシュ - ある程度はキャッシュに持ちつ - 無ければディスクか - それでもなければネットから

キャッシュに入れるには、

NSCache(ちょっとカッコいい NSDictionary)

を利用するとよい。

■スクロールのスナップ スナップが通常に機能すると、セルが長くなった時に読めない・・・。 - 上向き、下向きのスクロールの判別 - 位置座標、移動量を判別してスナップ - 高さが1画面に満たしているかを判別

■アニメーション UIView transitionFromView, UIViewAnimationOptionShowHideTransition を利用するのが自然だった

■サムネイル UITableView を横向きに使うのが良かった ScrollView を使うのは面倒

■特定の文字のスタイルを変更する CoreText を利用するのも良いが、描画する文字を一文字ずつ処理する。

  2011/11/23

辞書アプリ Metronome Pro の作者 cocos2d for iPhone レッスンノート著者

iOS5 では辞書が標準搭載

  • UITableView & UISearchBar で検索
  • 意味を表示
  • 候補を表示
  • 辞書の選択

意味を表示

UIReferenceLibraryViewController * controller = [[UIReferenceLibraryViewController alloc] initWithFrame];

で表示させるだけ。 よって、文字を取得する事はできない。

候補を表示

UITextChecker *_cheker = [[UITextCheker alloc] init];
guessesForWordRange:NSMakeRange(0, [searchText length])
inString: searchText
language: ["en_US"];

[UIReferenceLibraryViewController dictionaryHasDefinitinoForTerm: searchText];

辞書の選択

NSLocale の +(NSArray *)prefferedLanguage をオーバーライド

[[NSArray arrayWithObject: @"en"];

サンプル

  2011/11/23

iPad とレシートプリンタを繋ぎたい。 (AirPlay があるのにあえて使ってみる!)

ポスレジを iPad と レシートプリンタで実現するデモ・・・感動ものでした。。。

プリンタ機種

EPSON TM-T70 ・RS-232C(シリアルポート) ・IEEE1284(パラレル) ・USB20 ・100(10)BASE-TX ・無線LAN(IEEE802.11b)インターフェイス

iPad側のインターフェイス

・GKSession で Bluetooth、NetWork接続 ・NSStream経由でNetWork接続

GKSessionは、同一アプリからしか通信できない

NSStream しかない

NSStream

メモリ、ファイル、ネットワーク(ソケットを通じて)に配置されたデータのストリームオブジェクトを作る事ができる。

EPSON TM-T70

■RS232 etherNet Converter シリアル通信をイーサーネット上のソケット通信に変換するコンバータ

TCP、UDP、UART が利用できる。 ※UART シリアル通信を制御するチップ

カスタマディスプレイ(2行表示)では見づらいので、

iPad でディスプレイ表示!

実装部分

  • NSStreamDelegate 利用
  • CFStreamCreatePairWithSocketToHost
  • ポート番号9100番を指定
char s[3];
s[0] = 0x1b;

[_outputStream write:(unit8_t*)s max Length:sizeof(s)];
  • Shift-JIS のロムを持っているので、NSShiftJISSStreingENcoding を利用
  • サーバを置かなくても、LPRプロトコルを使って通信可能

実演

  • メインディスプレイは、ONKYO の フォトビューワー(製造中止w) ※AppleTV 経由で表示も可能
  • 商品一覧、金額は基本プログラム
  • デザイン部分は、WebView で表示

iPad 側の機能

  • 顧客マスター
  • 担当マスター
  • 店舗マスター
  • 消費税率
  • 支払い方法
  • 売上げ管理(釣り銭準備金、回収、雑収入など)

  2011/11/23

CMLocationManager

iPhone アプリのコンパスでは、iPhone を縦に傾けると方角が180度変わってしまうポイントがある。 地磁気と加速度からデバイスの向きを考慮した方角を算出 参考資料

OpenGL + 加速度センサで のグラフィックをそのまま表示(ARぽく)するとかなり震える。 加速度の値をそのまま使うとばらつきがある為、安定しない。

ローパスフィルターの適応して位置補正やる

ここら辺は大学の制御工学でやった気がするが、今の自分にはもうそんな学力はない訳で・・・。

CMMotionManager

またジャイロセンサー(CMRotationRate の値)を使うといい感じで補正できる。

バッテリーの問題

Energy Diagnostics で 60秒間計測 iPhone 4 iOS4.3.3

■アプリ起動のみ Energy Usage: 9/20

■方角取得のみ Energy Usage: 11/20

■加速度 + ジャイロのみ Energy Usage: 18/20

■OpenGL描画 動作周波数:30Hz 超点数:14000 Energy Usage: 16/20 20%

■すべて使用 Energy Usage: 18/20 CPU Activity:85%

■iPhone 標準カメラ Energy Usage: 18/20 CPU Activity:85%

Foursquare iOS API

baztokyo foursquare-ios-api

  2011/11/22

PHPフレームワーク FuelPHP が話題になったのでインストールしてみた。

詳しい記事は、PHP フレームワークの「FuelPHP」がスゴすぎる を参照に。

  • ORM、マイグレート対応しており、MongoDB、Redis も使えるとの事
  • 基本的にスタティックにコーディングするので(インスタンスを経由ラッパーしていると思う)ので書くコードが少なそう
  • Unitテスト(PHPUnit、Jenkins)対応
  • autoload 対応でライブラリ、ヘルパーの自動ロードができる
  • Scaffolding 対応(oilコマンド)
  • 多数のViewテンプレート対応

会社では独自フレームワークを使って、更にDBと連動してアプリ作成自動化を進めてますが、一人よがりなんですよね。 比較してみて良さげだったら切り替えようかと・・・

PHP フレームワークとして評価が高い「Codeigniter」の対抗として注目されているみたいです。

oil のインストール

RoR みたいにプロジェクトを作成するのに oil コマンドが必要なのでインストール

$ curl get.fuelphp.com/oil | sh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 244 100 244 0 0 705 0 --:--:-- --:--:-- --:--:-- 1410 password:

パスワードを聞かれるのは、/usr/bin にコマンドをいれるかららしい。

プロジェクト作成

$ cd Sites/ $ oil create blog Cloning into ./FuelTest... remote: Counting objects: 14115, done. remote: Compressing objects: 100% (4842/4842), done. remote: Total 14115 (delta 9635), reused 13321 (delta 9041) Receiving objects: 100% (14115/14115), 2.06 MiB | 666 KiB/s, done. Resolving deltas: 100% (9635/9635), done. Submodule 'docs' (git://github.com/fuel/docs.git) registered for path 'docs' ... Made writable: /Users/yoo/Sites/FuelTest/fuel/app/cache Made writable: /Users/yoo/Sites/FuelTest/fuel/app/logs Made writable: /Users/yoo/Sites/FuelTest/fuel/app/tmp Made writable: /Users/yoo/Sites/FuelTest/fuel/app/config

パーミッションを手動で変えたい場合は、

php oil refine install Made writable: /Users/yoo/Sites/FuelTest/fuel/app/cache Made writable: /Users/yoo/Sites/FuelTest/fuel/app/logs Made writable: /Users/yoo/Sites/FuelTest/fuel/app/tmp Made writable: /Users/yoo/Sites/FuelTest/fuel/app/config

public を Web ルートに

デフォルトだと、Webルートがプロジェクトディレクトリになってしまうので public を Webルートに設定する必要がある。 Appache の設定で、public をWebルートにするか、.htaccess で public/ へ rewirte 設定してやる。


Options -MultiViews


    RewriteEngine on
    RewriteRule (.*) public/$1 [L]

ファイル構成

.git .gitmodules README.md docs/ oil .gitignore CHANGELOG.md TESTING.md fuel/ public/

デフォルトだと、Git 管理される。 public/ fuel/ ディレクトリだけの構成 oil は拡張子こそないがPHPファイル(PHPコマンドで使うのかな?)

fuel/

app/ core/ packages/

RoR のような構成とはちょっと違うが、名前から大体想像がつくと思います。

fuel/app/

bootstrap.php classes/ config/ lang/ logs/ migrations/ modules/ tasks/ tmp/ views/

こう見ると、たくさんの機能がサポートされてる臭いがします。 config/ では、アプリの一般設定やDB設定ファイルがあり、開発/デプロイと分ける事が可能。 ローカライズ(デフォルト en)、XSS対応、cookie、モジュール管理、パスのルーティングなどなど多彩な設定が用意されています。

classes/ では

controller model view

といった、アプリ作成でお馴染みの顔ぶれが。 ただ、fuel/views というディレクトリもあるので使い分けは不明だが、テンプレート自体は app/views に HTML を記述するっぽい。 classes/view は、HTMLレンダリングする前にパラメータを変えたりヘルパー的な事を記述するような気がする。

public/

.htaccess assets/ index.php

.htaccess でリライトして、index.php が最初に読み込まれます。

/**
 * Set error reporting and display errors settings.  You will want to change these when in production.
 */
error_reporting(-1);
ini_set('display_errors', 1);

/**
 * Website document root
 */
define('DOCROOT', __DIR__.DIRECTORY_SEPARATOR);

/**
 * Path to the application directory.
 */
define('APPPATH', realpath(__DIR__.'/../fuel/app/').DIRECTORY_SEPARATOR);

/**
 * Path to the default packages directory.
 */
define('PKGPATH', realpath(__DIR__.'/../fuel/packages/').DIRECTORY_SEPARATOR);

/**
 * The path to the framework core.
 */
define('COREPATH', realpath(__DIR__.'/../fuel/core/').DIRECTORY_SEPARATOR);

// Get the start time and memory for use later
defined('FUEL_START_TIME') or define('FUEL_START_TIME', microtime(true));
defined('FUEL_START_MEM') or define('FUEL_START_MEM', memory_get_usage());

// Boot the app
require APPPATH.'bootstrap.php';

// Generate the request, execute it and send the output.
try
{
    $response = Request::forge()->execute()->response();
}
catch (HttpNotFoundException $e)
{
    $route = array_key_exists('_404_', Router::$routes) ? Router::$routes['_404_']->translation : Config::get('routes._404_');
    if ($route)
    {
        $response = Request::forge($route)->execute()->response();
    }
    else
    {
        throw $e;
    }
}

// This will add the execution time and memory usage to the output.
// Comment this out if you don't use it.
$bm = Profiler::app_total();
$response->body(
    str_replace(
        array('{exec_time}', '{mem_usage}'),
        array(round($bm[0], 4), round($bm[1] / pow(1024, 2), 3)),
        $response->body()
    )
);

$response->send(true);

// Fire off the shutdown event
Event::shutdown();

DOCROOT : doc パス登録 APPPATH : fuel/app パス登録 PKGPATH : fuel/package パス登録 COREPATH : fuel/core パス登録 FUEL_START_TIME : fuelphp 開始時間登録 FUEL_START_MEM : fuelphp メモリ容量登録

bootstrap.php で app のメインファイルを起動し、autoloader.php でオートロード(必ず読み込むファイル)等を管理しています。 CodeIgniter だと手動で書かなければいかない点が、FuelPHP では自動ロード可能って事ですね。

最後に、config.php を読み込んでいます。

コントローラーとビューの作成

■ビューファイル app/views/inquiry/index.php

普通にHTMLファイルを記述 レイアウトの分け方は現在不明

■コントローラーファイル app/inquiry.php

class Controller_Inquiry extends Controller
{
    /**
     * The basic welcome message
     * 
     * @access  public
     * @return  Response
     */
    public function action_index()
    {
        return Response::forge(View::forge('inquiry/index'));
    }

    /**
     * show how to use them.
     * 
     * @access  public
     * @return  Response
     */
    public function action_send()
    {
    }

}
  • クラス名は、Controller_コントローラ名(最初は大文字)
  • デフォルトは Controller を継承
  • ビューレンダリングは Response::forge() ,View::forge() を利用
  • Fuel独自の関数 new static を実装しており、静的メソッドで書く事が可能

Response 、Viewで使える関数は、fuel/core/classes/response.php ,view.php を参照するとよいかと。 ちなみに Viewに関しては、forge(), render(), factory() といった数種類の方法がある。

ただアクション名とファイル名が一致したら、レンダリングの記述は省いて自動レンダリングしてくれる機能は欲しいところです

Codeigniter の対抗になるか?

Codeigniter vs FuelPHP でも比較検討の記事が掲載。

FuelPHP は機能は良いけど、新しい機能への弊害や利用者数の少なさが問題のようですね。

  2011/11/21

WebGL の記事でちょっとだけ書いたんですけど、世の中に少しずつ作品が紹介されてるのを目にしますね。 Twitter で #webgl でリアルアイムでかなり頻繁に情報が飛び交ってます。

Ellie Goulding Lights

Ellie Goulding Lights VJ ですね!

Cérebro 3D em WebGL

Cérebro 3D em WebGL 脳のグラフィック表示

ThreeNodes.js

ThreeNodes.js モデル作成ツール? JSON で書き出せますが、用途不明。

Github でもソースが公開されています。 Github ThreeNodes.js

WebGL の基本

Hack The WebGL (WebGL勉強会) 日本だとここの勉強会が活発なんでしょうか? Hello World 的なサンプルもあります。

■glMatrix glMatrix ってのを使ってるらしいですが、glMatrix.js はイケてない て記事もあったり。。。 この表を見る限りライブラリーが乱立していてなかなか手が出しづらいですが、まずは 基本的な扱いを覚えないとです(汗)

  2011/11/19

iOS5 から AudioToolbox に MusicPlayer が追加された。 ※間違いが含まれている場合があるので注意

/*!
    @header MusicPlayer.h
    
    @abstract   API for Music sequencing and playing services
    
    @discussion
        Basic idea behind the Sequencing Services APIs:

            A MusicSequence contains an arbitrary number of tracks (MusicTrack)
            each of which contains time-stamped (in units of beats) events in time-increasing order.  
            There are various types of events, defined below, including the expected MIDI events, tempo, 
            and extended events.
            
            A MusicTrack has properties which may be inspected and assigned, including support
            for looping, muting/soloing, and time-stamp interpretation. APIs exist for iterating through the 
            events in a MusicTrack, and for performing editing operations on them.
            
            A MusicPlayer is used to play a sequence and provides control of playback rate and
            setting to a particular time.
            
            Each MusicSequence may have an associated AUGraph object, which represents a set
            of AudioUnits and the connections between them.  Then, each MusicTrack of the
            MusicSequence may address its events to a specific AudioUnit within the AUGraph.
            In such a manner, it's possible to automate arbitrary parameters of AudioUnits,
            and schedule notes to be played to MusicDevices (AudioUnit software synthesizers)
            within an arbitrary audio processing network (AUGraph). A MusicSequence or its tracks
            can also address a MIDI endpoint directly.
        
        The objects defined in this header are:
            Music Sequence - container of music tracks
            Music Track - a time ordered list of events
            Music Track Iterator - an object to iterate over events in a track
            Music Player - an object used to play a sequence
*/

シーケンスと演奏サービスのAPI と思いっきり明記されています。 ビート単位に関するタイムスタンプで、任意のトラックで利用可能。 ループ、ミュート、ソロ、タイムスタンプ解像度(?)をサポート。 再生レートコントロール、特定の時間設定が可能。 シーケンサーは、AUGraph オブジェクトに関連しており、AudioUnitsと連携する。

シーケンストラックは、AUGraph を含む 特定の AudioUnit イベントを対処する。 これで、AudioUnits の任意パラメータを自動化することはできる。 ノートをスケジュールすることで、任意のオーディオプロセスを含む MusicDevices(AudioUnit ソフトシンセ)を再生する事ができる

MusicSequence もしくはトラックは、MIDIエンドポイントを直接対処することができる。 - Music Sequence - MusicTrackを含む - Music Track - イベントリストのオーダー時間 - Music Track Iterator - トラック内のイベントを Iterate するオブジェクト - Music Player - シーケンス再生で使われるオブジェクト

include

#include 
#include 
#include 
#include 
#include 

ざっと見て、 - MIDIServices.h で シーケンスを利用できる - AUGraph.h で フィルタを利用でき、Instrument(いわゆるソフトシンセ)とも連動できる と捉えてよいのだろうか?

■MusicEventType 〜 AUPresetEvent

MusicEventType

/*!
    @enum MusicEventType
    @abstract music event types, including both MIDI and "extended" protocol
    @constant kMusicEventType_NULL  
    @constant kMusicEventType_ExtendedNote      note with variable number of arguments (non-MIDI)
    @constant kMusicEventType_ExtendedTempo     tempo change in BPM
    @constant kMusicEventType_User              user defined data
    @constant kMusicEventType_Meta              standard MIDI file meta event
    @constant kMusicEventType_MIDINoteMessage       MIDI note-on with duration (for note-off)
    @constant kMusicEventType_MIDIChannelMessage    MIDI channel messages (other than note-on/off)
    @constant kMusicEventType_MIDIRawData           for MIDI system exclusive data
    @constant kMusicEventType_Parameter,        general purpose AudioUnit parameter, added in 10.2
    @constant kMusicEventType_AUPreset,         the AU's user preset CFDictionaryRef (the ClassInfo property), added 10.3
*/
enum
{
    kMusicEventType_NULL                    = 0,
    kMusicEventType_ExtendedNote            = 1,
    kMusicEventType_ExtendedTempo           = 3,
    kMusicEventType_User                    = 4,
    kMusicEventType_Meta                    = 5,
    kMusicEventType_MIDINoteMessage         = 6,
    kMusicEventType_MIDIChannelMessage      = 7,
    kMusicEventType_MIDIRawData             = 8,
    kMusicEventType_Parameter               = 9,
    kMusicEventType_AUPreset                = 10
};
typedef UInt32      MusicEventType;

ノート、チャンネル、テンポ、メタといったタイプがある。

MusicSequenceLoadFlags

/*!
    @enum MusicSequenceLoadFlags
    @abstract Flags used to customise loading behaviour
    @constant   kMusicSequenceLoadSMF_ChannelsToTracks
            If this flag is set the resultant Sequence will contain:
            a tempo track
            1 track for each MIDI Channel that is found in the SMF
            1 track for SysEx or MetaEvents - this will be the last track 
            in the sequence after the LoadSMFWithFlags calls
*/
enum
{
    kMusicSequenceLoadSMF_ChannelsToTracks  = (1 << 0)
};
typedef UInt32      MusicSequenceLoadFlags;

SMFファイル読み込み時のフラグ フラグがセットされていたら、テンポトラックを1トラックに設定(?)

MusicSequenceType

/*!
    @enum MusicSequenceType
    @abstract   A sequence type
    @discussion Different sequence types to describe the basic mode of operation of a sequence's time line
                You cannot change a music sequence's type to samples/seconds if there are tempo events
                The type will also define how the sequence is saved to a MIDI file:
                    Beats - normal midi file
                    Seconds - midi file with SMPTE time
                    Samples - cannot be saved to a midi file
    @constant   kMusicSequenceType_Beats
                    The default/normal type of a sequence.
                    Tempo track defines the number of beats per second and can have multiple tempo events
    @constant   kMusicSequenceType_Seconds
                    A music sequence with a single 60bpm tempo event
    @constant   kMusicSequenceType_Samples
                    A music sequence with a single tempo event that represents the audio sample rate
*/
enum {
    kMusicSequenceType_Beats        = 'beat',
    kMusicSequenceType_Seconds      = 'secs',
    kMusicSequenceType_Samples      = 'samp'
};
typedef UInt32      MusicSequenceType;

ミュージックシーケンスタイプ - Beats - 通常のMIDIファイル - Seconds - SMPTE の MIDIファイル - Samples - MIDIファイルに保存できない

MusicSequenceFileTypeID

/*!
    @enum MusicSequenceFileTypeID
    @abstract   describes different types of files that can be parsed by a music sequence
    @constant   kMusicSequenceFile_MIDIType
                    read and write MIDI files
    @constant   kMusicSequenceFile_iMelodyType
                    read iMelody files
*/
enum {
    kMusicSequenceFile_MIDIType         = 'midi',
    kMusicSequenceFile_iMelodyType      = 'imel'
};
typedef UInt32      MusicSequenceFileTypeID;

ミュージックシーケンスファイルタイプ - kMusicSequenceFile_MIDIType - MIDIファイル読み書き - kMusicSequenceFile_iMelodyType - iMelody ファイル読み書き

通常は、kMusicSequenceFile_MIDIType で大丈夫かと

MusicSequenceFileFlags

/*!
    @enum MusicSequenceFileFlags
    @abstract   controls the behaviour of the create file calls
    @constant   kMusicSequenceFileFlags_EraseFile
                    Erase an existing file when creating a new file
*/
enum {
    kMusicSequenceFileFlags_EraseFile = 1
};
typedef UInt32 MusicSequenceFileFlags;

現在、 kMusicSequenceFileFlags_EraseFile しかない。 新規作成ファイル時に、ファイルが存在したら消す

MusicTimeStamp

/*!
    @typedef    MusicTimeStamp
    @abstract   The type used to refer to time values in a music sequence
*/
typedef Float64     MusicTimeStamp;

シーケンス時のタイムスタンプで、時間指定の基本の型です。

MIDINoteMessage

/*!
    @struct     MIDINoteMessage
    @discussion The parameters to specify a MIDI note
*/
typedef struct MIDINoteMessage
{
    UInt8       channel;
    UInt8       note;
    UInt8       velocity;
    UInt8       releaseVelocity;    // was "reserved". 0 is the correct value when you don't know.
    Float32     duration;
} MIDINoteMessage;

MIDI ノートのパラメーター(UInt8)で、チャンネル、ノート、ベロシティ、リリースベロシティ、デュレーションがある。

MIDIChannelMessage

/*!
    @struct     MIDIChannelMessage
    @discussion The parameters to specify a MIDI channel message
*/
typedef struct MIDIChannelMessage
{
    UInt8       status;     // contains message and channel
    
    // message specific data
    UInt8       data1;      
    UInt8       data2;
    UInt8       reserved;
} MIDIChannelMessage;

MIDIチャンネルメッセージのパラメータ(UInt8)で、ステータス(メッセージとチャンネル)、データ1、データ2、予約がある。

MIDIRawData

/*!
    @struct     MIDIRawData
    @discussion Generally used to represent a MIDI SysEx message
*/
typedef struct MIDIRawData
{
    UInt32      length;
    UInt8       data[1];
} MIDIRawData;

MIDI生データで、エクスクルーシブメッセージとして利用

MIDIMetaEvent

/*!
    @struct     MIDIMetaEvent
    @discussion The parameters to specify a MIDI meta event
*/
typedef struct MIDIMetaEvent
{
    UInt8       metaEventType;
    UInt8       unused1;
    UInt8       unused2;
    UInt8       unused3;
    UInt32      dataLength;
    UInt8       data[1];
} MIDIMetaEvent;

MIDIメタデータ MIDIメタデータのパラメータは、metaEventType(UInt8)、未使用1〜3(UInt8)、データ長(UInt32)、データ[1](UInt8)がある。 (これはMIDIデータの生の構造かと)

MusicEventUserData

/*!
    @struct     MusicEventUserData
    @discussion Provides a general struct for specifying a user defined event. 
    @field      length
                    the size in bytes of the data
    @field      data
                    size bytes of user defined event data
*/
typedef struct MusicEventUserData
{
    UInt32      length;
    UInt8       data[1];
} MusicEventUserData;

開発者が独自に定義できるユーザデータイベントパラメータ(構造体)

ExtendedNoteOnEvent

/*!
    @struct     ExtendedNoteOnEvent
    @discussion The parameters to specify an extended note on event
*/
typedef struct ExtendedNoteOnEvent
{
    MusicDeviceInstrumentID     instrumentID;
    MusicDeviceGroupID          groupID;
    Float32                     duration;
    MusicDeviceNoteParams       extendedParams;
} ExtendedNoteOnEvent;

拡張用ノートイベントで音色ID、グループID、デュレーション、拡張パラメータ 拡張データの規格に対応していれば、利用できる? MusicDeviceInstrumentID 、MusicDeviceGroupID で MusicDevice を振り分けられる?

ParameterEvent

/*!
    @struct     ParameterEvent
    @discussion The parameters to specify a parameter event to an audio unit.
*/
typedef struct ParameterEvent
{
    AudioUnitParameterID        parameterID;
    AudioUnitScope              scope;
    AudioUnitElement            element;
    AudioUnitParameterValue     value;
} ParameterEvent;

AudioUnit 用の特殊イベントパラメータ(構造体) AudioUnit のパラメータがよくわかっていないので、何とも・・・

  • AudioUnitParameterID - filter cut-off frequency がある
  • AudioUnitScope - 0 〜 1024 の AudioUnit スコープ で、global, input, output がある
  • AudioUnitElement - スコープは1つ以上のメンバーを持ち、Elementによって関連づけられる。 input bus 1 は 入力スコープ
  • AudioUnitParameterValue - AudioUnit パラメータ値

これは、iPhone Core Audio の本を読み直しですね。。。 ■参考 スコープについて

ExtendedTempoEvent

/*!
    @struct     ExtendedTempoEvent
    @discussion specifies the value for a tempo in beats per minute
*/
typedef struct ExtendedTempoEvent
{
    Float64     bpm;
} ExtendedTempoEvent;

テンポイベント(30〜250くらい)で、bpm(Float64) が利用可能

AUPresetEvent

/*!
    @struct     AUPresetEvent
    @discussion The parameters to specify a preset for an audio unit.
*/
typedef struct AUPresetEvent
{
    AudioUnitScope              scope;
    AudioUnitElement            element;
    CFPropertyListRef           preset;
} AUPresetEvent;

AudioUnit用の、特殊プリセットパラメータ(構造体)

これも、AudioUnit のパラメータがよくわからないので・・・ シーケンスするときにサンプル音と連動する。

pngファイルの軽量化
Google DriveのIconを再起的に削除
php-markdownでバニラPHPなコードブロック処理
laravel-ffmpeg を使う
2021年版 Ubuntu + certbot + Let's Encrypt でサーバ証明書設定
GihHub のデフォルトでない master ブランチを checkout する
マルチログインで未認証のリダイレクト
Homebrew で Redis をインストール
CSS だけでスムーズスクロール
EC-CUBE4 で Gmail の smtp を利用する
Amazon Linux 2 の amazon-linux-extras とは
UNIQUE カラムのバリデーションで自分自身を除外して更新
フォーム有効期限切れで Page Expired をリダイレクト
ログを日付でローテーションやクリアや削除
Homebrew で PHP8.0 から PHP7.4 にダウングレード
Big sur で zsh 移行と Homebrew アップグレード
Mac に minikube をインストール
途中から .gitignore に追加する
Larevel 6.x から Laravel 8.x にバージョンアップ
Composer で Allowed memory size (メモリ不足)エラー
Blade でカスタムクラスを利用する
git push git pull にブランチ指定せずに実行する
git pull や git push できなくなったとき
Docker のコンテナからホストOS に接続
Mac で ローカル IP アドレス(ipv4)のみを表示する
ホストOS から Docker の MySQLコンテナに接続
caching_sha2_password のエラー
node-config で環境設定ファイルを利用する
rootパスワードを初期化(再設定)する
Git から clone したときのエラー対処
Mac に MySQL をインストール
Mac に PostgreSQL をインストール
Laravel 環境構築 - Mac ネイティブ編
Firebase 入門 - Firebase とは
Firebase 入門 - CLI インストールとデータベースの設定
AWS 無料枠(t2.micro)で容量とメモリエラー
Cloud9 を起動する -初心者編-
gcloud で GCEインスタンスを起動してみる
AWS CLI と jq でインスタンス一覧を整形して表示
React と Laravel7 のプロジェクトを作成する
Homebrewインストール-2020年版
3直線で囲まれた範囲塗りつぶし
PuLP で線形最適化問題を解く
カスタムのペジネーションを作る
node-sass を使って sass をコンパイルする
Log ファサードでSQLログを分離して書き出す
いちから始める Docker - 複数のコンテナを使う - (2020年)
いちから始める Docker - docker-compose を使う - (2020年)
AWS ECR を使ってみる
Laravel7 でマルチ認証