井原プロダクトのBLOG

Since 2013。個人でアプリ作っています。

簡単選曲の音楽アプリできました

https://itunes.apple.com/jp/app/musa-music-player/id1056067671?mt=8

Apple Musicの登場によって、iPhoneのミュージックプレーヤーは、大きく変わりました。メイン画面下のTABに表示されているのは、My Musicの他にはRadioとかConnectなどのオンライン系のサービスへのLinkとなり、自分のライブラリーの音楽を聴くのがメインの方にとっては、選曲のメニューが奥に引っ込んでしまい正直言って使いづらい。

という事で、かつてのiPodの様な操作性を備えたミュージックプレーヤー Musa Music Playerをリリースしました。

ぱっと見でわかると思いますが、ジャンル、演奏家、作曲家、アルバム、曲のカテゴリーで検索できます。更に特徴的なのは、各カテゴリーの検索がキープされるため、AND検索ができる事です。

なので、こんな検索もできます。

作曲家 = bach かつ

演奏家=Gould かつ

アルバム=Goldberg

とか、

演奏家 = Miles

アルバム = ‘Round About Midnight

など。

ですから、沢山のCDをiPhoneに入れていても大丈夫、簡単に目当ての曲を選曲することができます。


無料ですので、ぜひご利用ください。

やよいの青色申告オンライン

個人事業主のみなさん、確定申告頑張ってますか?

私は、Mac使いのため、表記のクラウドサービスを使っているのですが、時々数字が入らなくなって困っています。

例えば、固定資産の登録で、本年中の償却期間というところに4という数字が入らない、、、。いつも固まってしまうため、その都度ブラウザを閉じて再チャレンジしていたのですが、それでも入らない。

さんざん悩んだ末、Safariを閉じてChromeで入れたら、、、




入りました。ちゃんちゃん。

スイスフラン急騰について見てみた

昨日の夕方、新宿御苑前サンマルクカフェでお茶して、その後フレンチレストランでピアノのお友達と楽しく食事をしている頃、スイス国立銀行がスイス フラン(CHF)の対ユーロ(EUR)上限を廃止することを発表、それを受けて、スイスフランが急騰(していたんですね。

為替は全くの素人ですし、FXも、今は全然やっていないのですが、ネットで「〇〇百万円の追証が発生した。死亡!」とか、「ん千万円儲かった、もう会社辞める!」とか言っている人がいて興味を持ったので(=この機会にいっちょ儲けられないか?と)何があったのか見てみました。

元々、CHFには1ユーロ1.2CHFの壁があって、それを下回ると政府が介入していたそうで、それが昨日撤廃されたことで1.04CHFまで上がっています。ユーロを基準に考えると、対スイスフランで大暴落なんですが、CHF/EURのおお下がりチャートが多くネットに掲載されているため、スイスフラン大暴落!なんて言ってる人がいますが、逆です。スイスフランは大暴騰です。ややこしいですね。

対円で言うと、急騰前の相場は、大体 114〜115円くらい。これが18:30-18:50の間に156.4円まで行っていますね。なので、115円で20万CHF買って、156円で決済すれば820万円の儲け!!20倍レバレッジだと、115万円が820万円になる。で、当然その逆のポジションをとれば820万円の損。
しかも、今回急に変動したからロスカットが働いていないケースが多発しているみたい。

儲かった人は、さっさと換金して銀行なりに資金を移すでしょうし、損した人は、払えって言われてもそんなお金ないから払えないってなるだろうし、そうなるとFXの会社が厳しいのかな。

しかし、今ってコンピュータが自動で売り買いしちゃうから、こうして一瞬で相場が動くんでしょうね。怖い怖い、やっぱりやめておこう。

* もし誤って理解しているところがあったらご指摘下さい。

iPhone6&6Pに非対応のアプリの画面設定

さっきはまったのですが、iPhone6&6Pに非対応のアプリをシミュレータで実行したときに、そのまま拡大して実行して欲しいところを、実際の大きさのままで(つまり画面の左右が余ってる表示で)実行されちゃうという事が起きた。

どうすれば良いかいろいろ過去のアプリと設定を見比べていたところ、原因はココにありました。


このLauch Screen FIleというところがカラになっていないとダメみたいです。原因とかは、後で調べます。取り急ぎ、、。

正確なメトロノームアプリの作成

以下は127bpmにおいて音を鳴らすべき時間の理論値と、実際に出すタイミングを比較してみたものです。

基本的なエンジン部分は、ほぼこちらの作りと同じで、実行結果は、Dataの通り誤差が1ms以内に収まるようになりました。0.002の差があるのに、結果が0.001というのは、1ms以下の数値が丸まっていると思われ。

http://stackoverflow.com/questions/4485072/accurate-timing-in-ios

2014-12-11 15:19:49.127 Metronome[5286:1146464] 理論=0.000 実際=0.000 差分=0.000
2014-12-11 15:19:49.685 Metronome[5286:1146464] 理論=0.529 実際=0.530 差分=0.001
2014-12-11 15:19:50.219 Metronome[5286:1146464] 理論=1.057 実際=1.059 差分=0.001
2014-12-11 15:19:50.753 Metronome[5286:1146464] 理論=1.586 実際=1.587 差分=0.001
2014-12-11 15:19:51.263 Metronome[5286:1146464] 理論=2.115 実際=2.115 差分=0.001
2014-12-11 15:19:51.797 Metronome[5286:1146464] 理論=2.643 実際=2.643 差分=0.000
2014-12-11 15:19:52.331 Metronome[5286:1146464] 理論=3.172 実際=3.173 差分=0.001
2014-12-11 15:19:52.865 Metronome[5286:1146464] 理論=3.700 実際=3.702 差分=0.001
2014-12-11 15:19:53.375 Metronome[5286:1146464] 理論=4.229 実際=4.230 差分=0.001
2014-12-11 15:19:53.909 Metronome[5286:1146464] 理論=4.758 実際=4.758 差分=0.000
2014-12-11 15:19:54.443 Metronome[5286:1146464] 理論=5.286 実際=5.288 差分=0.001
2014-12-11 15:19:54.978 Metronome[5286:1146464] 理論=5.815 実際=5.815 差分=0.000


だがしかし!

聞いた感じ、微妙に正確じゃないんです。これって人の感覚が1msを感知しているというより、オーディオ側のレスポンスが揺らいでるって事だよね orz

ということで、3種類試してみました。

  • AVAudioPlayerによる再生(これが今までの)
  • SystemSound Playerによる再生
  • OpenALを用いた再生

結果、、、、どれも同じ(爆)


おそらく別のアプローチが必要ですね。

メトロノームの正確性の追求

NSTimerを使うのは論外として、NSThreadを使ってタイマー処理を別にして、そのThreadのプライオリティーをあげて、というのが常套手段の様なのですが、それほど効果を感じられないです。

http://stackoverflow.com/questions/4485072/accurate-timing-in-ios

[NSThread setThreadPriority:1.0];

ってところがキモなのですが、これがあるのとないのとで、さほど変わりません。
超正確な「Metronome Star」とかどうやってるんだろう、、。

つづく

アプリ第4弾「練習カメラ」リリース

簡単操作の練習用カメラアプリができました!!

ピアノを練習していて、もっと簡単に録画再生ができないものか?といつも考えていました。iPhoneの標準のカメラを使うと「録画開始=>再生=>カメラに戻る」という一連の操作を行うには、6回の画面タップが必要です。録画の度にこれでは、練習の集中が途切れてしまいます。しかも、撮った動画がどんどん保存されてしまうので、後で消さないといけません。

そんな面倒を解決したい!というので生まれたのが「練習カメラ」。これは、同じ操作をするのに1回も画面をタップする必要がありません。操作はiPhoneに手をかざすだけ。

一度かざすと録画開始、もう一度かざすと録画停止、そして自動再生が始まります、終わったら手をかざして録画待機画面に。保存したいときだけ「保存」をタップする様になっています。これは切符がSUICAに変わった以来の大改革です(笑)。

無料ですので、iPhoneユーザの方はぜひお試しください。

また、アプリからピアノの横にiPhoneを設置できるスタンドをご購入いただけるようになっています。こちらもぜひよろしくお願いします。

技術的には、近接センサーを使っています。これ、ちょっと動作に癖があって、意外と実装には苦労しました。横向きでは動かないとか、Event発生にはON/OFFがあって、ONの状態で近接センサーをdisableにすると、次はOFFになったときしか検知しないとか。かといってずっとenableのままだと妙に感度が良くて、Video側の処理を待たずしてStatusが変わってダウンするとか、、。

それから、iPADには近接センサーがないため、同じ動作事はできないのですが、Appleの規定上、iPhoneアプリiPADでも動かないといけないため(実際、一度リジェクトされました。動かないアプリは結構あるんだけど、文句言っても仕方ない、、、)iPADでは手をかざすという動作ではなく、画面のどこかを触ってもらうことにしています。透明ボタンを画面いっぱいに配置しています。

また、UIImagePickerControllerで撮った動画は、明示的に消さないと消えません。これも想定外でした。ずっと保存されていくので、カメラ終了時、またアプリを落としたときなどのタイミングで、消去しないといけません。

@interface ViewController ()
NSString *pathToVideo;

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSURL *videoURL  = [info valueForKey:UIImagePickerControllerMediaURL];
<span class="deco" style="color:#FF0000;">    pathToVideo = [videoURL path];
</span>    //PickerControllerを閉じる
    [self dismissViewControllerAnimated:YES completion:nil];

//   取った画像の再生
    NSURL *url = [info valueForKey:UIImagePickerControllerMediaURL];
    playerItem = [[AVPlayerItem alloc] initWithURL:url];
    [playerItem addObserver:self forKeyPath:@"status" options:0 context:&ItemStatusContext];
    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(playerItemDidReachEnd:)
     name:AVPlayerItemDidPlayToEndTimeNotification
     object:playerItem];
    player = [AVPlayer playerWithPlayerItem:playerItem];
    [playerView setPlayer:player];
    //再生開始
    [player play];
}


-(void) deleteFile
    {
    //ここで録画したファイルを消す
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:pathToVideo]) {
        NSError *error;
        // Attempt to delete the folder containing globalDel.videoPath
        
        if ([fileManager removeItemAtPath:[pathToVideo stringByDeletingLastPathComponent] error:&error] != YES)
        {
            NSLog(@"Unable to delete file: %@", [error localizedDescription]);
        }else{
            NSLog (@"消去成功");
        }
        
    } else {
        NSLog (@"消去失敗");
        
    }
}

アプリのデモ動画