投稿

2018の投稿を表示しています

[Swift] MIDIデータの再生

先日のApp審査の却下を受けて、UIBackgroundModes Keyをオフにして再生する方法を調査。 結論としては、AudioKitのフレームワークは使用せず、Appleが提供しているフレームワークで実現することにしました。 シーケンサー MIDIデータを再生するために、下記のオブジェクト利用。 var musicSequence : MusicSequence? var musicPlayer : MusicPlayer? var musicTrack : MusicTrack? これだけだと、サウンドフォントを使った再生がうまくできなかったので、AUGraphも使いました。 var processGraph : AUGraph? var chordUnit : AudioUnit? var ioUnit : AudioUnit? var chordNode = AUNode() var ioNode = AUNode() まずは、初期化。 init() { NewAUGraph(&processGraph) NewMusicPlayer(&musicPlayer) NewMusicSequence(&musicSequence) MusicSequenceNewTrack(musicSequence!, &musicTrack) MusicSequenceSetAUGraph(musicSequence!, processGraph) MusicPlayerSetSequence(musicPlayer!, musicSequence) setup() loadSF2Preset(unit: chordUnit!) } private func setup() { var cd:AudioComponentDescription = AudioComponentDescri

[iOS] Appの審査

イメージ
先日、Appを審査に出したら、Rejectされました。 Rejectの理由 申請したAppは、バックグランドモード有効(Audio)となっているが、バックグランドモードにしても音がならないよ! ってことらしい。 はい。 フォアグランドの利用しか想定していないので、バックグランドモードでは音がならなくても問題ないです。 では、なぜ、バックグランドモードを有効にしたのか? 答えは、エラーを回避するため です。 Appで何が起きているのか Background Modesをオフにします。  で、Appを実行してみます。 AKMIDISampler()の実行前 AKMIDISampler()の実行後 AKMIDI.swift:init():63:Initializing MIDI CheckError.swift:CheckError:179:Error: kMIDINotPermitted: Have you enabled the audio background mode in your ios app? フレームワーク(AudioKit)でエラーが発生します。 バックグランドモードが有効になってない! だって。 kMIDINotPermitted・・・は、CoreMIDIのエラーのようなので、AudioKitのエラーというよりは、Appleで提供されているモジュールのエラーと思われます。 バックグランドモードを有効にすると、このエラーは出なくなります。 バックグランドで再生はしないので、できることならバックグランドモードは無効にしたい。 一方で、AppleのDocumentには、 Beginning in iOS 6, apps need to have the   audio   key in their   UIBackground Modes   in order to use CoreMIDI’s   MIDISource Create(_: _: _:)   and   MIDIDestination Create(_: _: _: _: _:)   functions. These functions return kMIDINo

[Swift] UISliderをカスタマイズしてみる

イメージ
iOSの標準コントロールに、UISliderというのがありますが、現在の値を表示したいと思ったことはないでしょうか。 プロパティを探してもそれらしいものが見つけられなかったので、UISliderを継承してオブジェクトを作ってみました。 UISlider 今回作成するオブジェクト 環境 MacOSX 10.14 Xcode 10.1 Swift 4 Target iOS 9.0 実現する内容 スライダーの値を表示する スライダーの上に見出し(タイトル)を表示する 増加量(ステップ量)を指定できるようにする 実装 SUISlider UISliderを継承して、SUISliderを作成します。 ソースの全体像は下記の通りです。 import UIKit public class SUISlider : UISlider { var labelTitle: UILabel var valueWidth: CGFloat = 60 var stepValue : Float = 0 private var labelValue: UILabel private let SPACING: CGFloat = 8 public override init(frame: CGRect) { labelTitle = UILabel() labelValue = UILabel() labelValue.textAlignment = NSTextAlignment.right super.init(frame: frame) self.addSubview(labelTitle) self.addSubview(labelValue) self.addTarget(self, action: #selector(self.onValueChanged(sender: )),

[Swift] AudioKitを使ってみる

イメージ
iOSで音を鳴らす方法を探してみたところ、AudioKitというフレームワークを使うと、便利そうだったので、使ってみることに。 フレームワークの利用にあたり、CocoaPods前提の情報はたくさんありましたが、 ・Projectファイルを勝手に書き換える ・バージョンが変わるとエラーが出る など、ネガティブな情報も多かったので、CocoaPodsを使わない方法での利用をしてみました。 環境 macOS Mojave (10.14) Xcode 10.1 iOS Target : 9.0 Swift Langage Version : Swift 4.2 AudioKitのダウンロード とりあえず、フレームワークを入手しないと始まらないので、サイトからダウンロードします。 AudioKit :  https://audiokit.io/downloads/ Projectへの組み込み xcodeでプロジェクトを開いて、ダウンロードしたフレームワークをドラッグ&ドロップで追加。 ファイルがごちゃ混ぜになると醜くなるので、私はフォルダを分けてわかりやすくするために、Frameworksというフォルダを作って、その下に追加してます。 フレームワークを追加すると、importができるようになります。 コンパイル はい。ここでハマりました。 ビルドを行うと、エラーが出ました。 ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) x86_64が見つからない? ようなので、プロジェクトファイルのBuildSettingにある Valid Architecturesにx86_64を足してみたりもしましたが、エラーは解消されず。。。 ダウンロードしたAudioKit内には、README.mdがあって、これを見ると、 Make sure to add `-lc++` to the **Other Linker Flag

[Music] DTM初心者のためのドラム打ち込み その2

イメージ
目的 ドラム譜を見て打ち込みをする人を対象に、楽譜の奏法と打ち込みについてわかるようになる 自分で曲を書いてる人や耳コピで打ち込みをする人にとっては参考にならないかもです 楽譜と奏法 アクセント アクセントはバンド譜でも出てくるのでわかる方も多いかと思います。 音符の上に付いてる「>」とか「^」ですね。 「>」も「^」も他の音よりも大きく叩くことになります。 クラッシュは、ライドと区別するためにアクセント付きがクラッシュを意味してることもあります。 「^」は、バンド譜では出てこないかもしれませんが、吹奏楽やマーチングではよく出てきます。「>」よりも強いアクセントになり、メリハリをつけるためにオープンリムショット(打面の真ん中とフープを同時に叩く奏法)にすることが多いです。 GM音源だと、残念ながらオープンリムショットに該当する音がありません。 DAWなどに付いてる標準のドラム音源だと、それっぽい音も含まれてますが、明確に使い分けたものはないかもしれないです。 私が使っているドラム音源(BFD3.0)だと、リムショットの音は用意されています。 フラム(装飾音符) 上の楽譜で、2小節目の4拍目にある小さな音符です。 これは、4拍目の音の前に小さな音を足すことを意味してます。 演奏には2つの解釈があり、曲調によって使い分けることになります。 (1) メインとなる音を拍の頭に置いて、装飾音符を拍の前に叩く (2) 装飾音符を拍の頭に置いて、メインとなる音を拍の後で叩く 多くの場合は、(1)のケースになりますが、重い感じを出したい場合は、(2)にすると雰囲気が出ます。 装飾音符の位置は、64分音符で配置するといい感じに聞こえます。 フラムの音については、音源で用意されていることもありますが、私は使ってません。 理由は、フラムの種類によっては対応できないためです。 例えば、こんなのです。 装飾が2つ、3つある場合、用意された音では表現できなかったりします。 打ち込みだと、これらは表現はできます。 2つ、3つ続く場合、64分音符で並べると、粒が出でないので、32分音符の3連譜で音を並べてます。 ロール ロールには、オープ

[Music] DTM初心者のためのドラムフィルイン

イメージ
目的 ドラムのフィルインを作れるようになる。 リズムパターン 一番基本となる16分音符をベースにリズムを考えてみます。  16分音符は、通常は右(R)、左(L)・・・と交互に叩きます。 1拍(16分音符4つ)のうち、1つ音を省いてみます。 1つ目、2つ目、3つ目、4つ目をそれぞれ省くと次のようになります。 音を2つ省いてみます。 12、23、34、14の音を省くと次のようになります。 1拍単位のリズムを組み合わせて、リズムパターンを作ってみます。 例) 組み合わせは、何通りもあります。 自分の好みのリズムパターンを探してみてください。 リズムパターンができたら次に、どの楽器を叩くか決めていきます。 叩く楽器を決める際は、楽器の配置と手順を考えます。 例) 応用パターン 16分音符2つを3連符に置き換えると、さらにバリエーションが増えます。 ただ3連符をそのまま叩くと、次の音は左手から始まります。 そこで、2つ打ちを使って手順を操作するケースがあります。 ケースバイケースなので、フレーズごとに使い分けると良いと思います。 2つ打ちを組み合わせることで、叩く楽器を決める際の選択肢を増やすことができます。 応用パターンを使ってフィルインを作ってみると、こんな感じになります。 このフレーズを打ち込みしてみます。 最初のLLは2つ打ちを想定しているので、演奏すると音が弱くなりがちのため、小さめにしてます。 Tomの音は、SDの音よりも目立ちにくいため、大きめにします。 3連符を絡めたパターンはアクセントになるので結構使えます。 2拍フィルインだと、このパターンを多用することが多いです。 曲の出だしにも使うことができますので、結構多用してます。(笑 リズムパターンの組み合わせで、様々なフィルインが作れます。 曲の雰囲気に合わせて、リズムを選んで組み合わせてみてください。

[Music] DTM初心者のためのドラム打ち込み

イメージ
目的 DTMでドラムの打ち込みをそれっぽく聞こえるようになる。 すでに、それっぽく聞こえるように打ち込みができる人には、参考にならない情報と思います。 ドラムの説明 演奏者からみた、一般的なドラムの配置は、図1のようになります。 図1 BD(Bass Drum) BDにはペダルを付けます。右足でペダルを踏んで音を出します。 一番低い音で、ドン・ドン となってるやつです。 SD(Snare Drum) 一番馴染み深い音だと思います。 大抵の曲では、2拍目、4拍目になってる パン!ってやつですね。 左手で叩くことが多いです。 Hi-Hat ビートの刻みには欠かせないものですね。 あまり主張はしてないですが、チキチキなってるやつです。 HiHatには、ペダルが付いてて、左足でペダルを踏みます。 ペダルを踏み込むと2枚のシンバルが閉じて(Close)、叩くとチキチキした音になります。 ペダルを踏まない(踏み込む力を抜く)と、2枚のシンバルが開いて(Open)、叩くとシャカシャカした音になります。 踏み込み具合で、2枚のシンバルの閉じ具合が変わるので、力加減で、Close、Half-Open、Full-Openなど、実際の演奏では使い分けてたりします。 DTMの一般的な音源だと、CloseとOpenの2種類と思います。 左足でペダルを踏む(例えば拍をとる)と、Close/Openが繰り返されるので、チッチッと音が出ます。これが、Pedal Hi-Hatになります。 Hi-Tom 、Low-Tom フィルインなどで良く使われます。ドゥーンってやつです。Hiが高い音で、Lowが低い音です。 DTMの音源では、Hi、Middle、Lowの3種類の音が用意されていることもあります。 タム3つの配置は、Hi-Tomが、SDの左前に配置されて、MiddleとLowがBDの上に並ぶ感じになります。(プレーヤーの好みによって配置は変わりますが) Floor-Tom こちらもフィルインで良く使われます。これも低い音でドゥーンってなります。 DTMの音源によっては、HiとLowの2種類用意されていることがあると思います。 配置としてはフロアタムを横並

[Swift] UITextView を使って、rtf や rtfd を表示する

イメージ
UITexiViewを使うと、リッチテキスト(RTFファイル、画像付きだとRTFD)を表示することが来ますが、変更履歴、使い方 など、いくつかの長文を表示したいケースがあると思います。 そこで、表示したい文書ファイルを引数にして内容を表示するようにしてみました。 ViewControllerの作成 初期化時にタイトル、文書ファイルのURL、文書の種類を引数で受け取ります。 import UIKit class TextViewController : UIViewController { let txvAbout = UITextView() var viewTitle:String = "" var url:URL! var docType:NSAttributedString.DocumentType! init(title:String, url: URL, docType: NSAttributedString.DocumentType) { super.init(nibName: nil, bundle: nil) self.viewTitle = title self.url = url self.docType = docType } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } 引数で受け取った情報は、クラス内に保持しておきます。 次に、UITextViewを定義します。 今回はUITexiViewしか配置しないため、ViewController内にベタ書きしましたが、凝ったレイアウトにしたり、レイアウトを差し替えたりする場合は、View用のファイルを作成して、外に切り出しても良いと思います。 override func viewDidLoad() { super.viewDidLoad()

[Swift] Header - Items形式のデータの読み書きを行う

イメージ
ヘッダデータ[1]と明細データ[0...n]を1つのデータの塊として、 ファイルに保存したり、読み込んだりしたくて、試行錯誤しました。 DBにした方が楽なんじゃない? とか思ったけど、DBにするほどデータも無かったので 、意地でもファイルで実現してやる! ってことで、なんとか動きました。 扱うデータのイメージ <ヘッダデータ> [1]  伝票番号   orderNo  仕入先コード vendorCode  仕入先名   vendorName <明細データ> [0...1]  明細番号   itemNo  明細テキスト itemText  数量     quantity ヘッダは必ず存在し、明細は0以上の可変を想定。 データ受け渡し用の構造 struct DataEntity { // Header var orderNo: Int! var vendorCode: String! var vendorName: String! // Items var items: [Item]! init(){ orderNo = 0 vendorCode = "" vendorName = "" items = [] } } struct Item { var itemNo: Int! var itemText: String! var quantity: Int! init(){ itemNo = 0; itemText = "" quantity = 0 } } コード データをファイルに保存する func writeData(dataEntity: DataEntity){ var data:Dictionary = [String:AnyObject]() // Header data["orderNo"] = dat

[Swift] StoryBoardを使用しない - 多言語対応

イメージ
多言語対応してます! って言えるとカッコイイかも? と思い、 必要ないかもしれませんが、仕組みを組み込んでみました。(笑 手順 1. Stringファイルを追加する ファイル名は「Localizable.string」とします。 2. プロジェクトのプロパティを開く 3. Localizationsで言語を追加 + ボタンを押して、言語を選択する。 先ほど追加した「Localizable.string」を選択。 4. Stringファイルが言語ごとに用意されていることを確認 Localizable.stringを編集 言語ごとにファイルが用意されているので、言語に合わせてテキストを編集します。 書式は、"任意のID" = "テキスト"; となります。 セミコロン(;)で区切らないと、コンパイルが通りませんので注意です。 Localizable(English) "label-RoundUnit" = "Round Unit"; "label-Rounding" = "Rounding"; "label-TotalAmount" = "Total Amount"; "label-CalcTotal" = "Calc.Total"; "label-CalcResult" = "Calc.Result"; "CalcTypeDIF" = "Difference"; "CalcTypeFIX" = "Fix"; Localizable(Japanese) "label-RoundUnit" = "丸め単位"; "label-Rounding" = "端数処理"; "label-TotalAmount" = "合計金額"; "label-Ca

ソフトウェア品質について思うこと

イメージ
私の主観なので、考え方の1つとして参考になればと思います。 ソフトウェア品質って? システム構築のプロジェクトをやってると、毎回こんなことを言われます。 ・チェックリストの件数と密度は? ・不良の摘出件数と密度は? ・どんなバグが出てるの? 品質向上施策はしたの? まぁ、システム開発に携わった方なら、普通に言われることと思います。 「動作不良がなく、仕様通りに正しく動作する。」 これ自体は正しいことと思います。 ただ、私としては、「これだけでは足りないのでは?」と思うわけですよ。 例えば、 仕様通りに動作するけど、ソースはスパゲッティ状態で、開発した人しか理解できないプログラム 「仕様通りに動いているので、品質は確保できている」と言えるけど、同時に「開発した人にしか理解できないソースは、修正時にデグレを起こす可能性が高く品質が悪い」 とも言える。  結局、品質って良いの? 悪いの? ってなりますよね。 これは「品質」をどう定義しているか? の違いによるものと思ってます。 ソフトウェア品質の定義 ソフトウェアの品質には、いくつかの観点があると思います。 私の場合、下記の観点で品質を見るようにしてます。 正確性(仕様通りに機能すること) 安全性(想定外の事象が起きた時、安全な方向に処理が倒れること) 操作性(ミスを起こしにくく使いやすいこと) 保守性(機能拡張、仕様変更に対応しやすいこと) 性能(人がストレスを感じない程度に応答が返ってくること) 1. 正確性 ソフトウェアが正確に動作しないのは致命的ですから、これは必須条件です。 仕様に書かれている通りに動作しないものは、不良として検知され修正をすることになりますので、品質を評価する上で数値化もしやすく、誰もが意識していることだと思います。 2. 安全性 これは、仕様に書かれていないことをどれだけハンドリングができているか? ということになります。 例えば、仕様で 処理済み件数と総処理件数を引数で受け取り、進捗率を返す。 進捗率は、 (処理済み件数/総処理件数)×100 で算出する と書かれていたとします。 何も考えずにコーディングするとこんな感じだと思います。 public float(int comp