クロスプラットフォームなゲーム開発で音を鳴らすにはOpenALが定番っぽいです。Mac、Windows、iOS、Androidで利用可能だそうで。しかしOpenALだけではwavファイルなどの音声ファイルを扱うことができません。そこで良さげなのがOpenALのユーティリティライブラリであるALUREです。wavファイルはもちろん、Ogg Vorbis、FLACなどにも対応しています。
しかし、このALUREをiOSで使うための情報が見つからなかったので結構苦労しました。なので記事にまとめておこうと思います。
記事執筆時の環境
iOSでOpenAL+ALUREを使う
OpenALの準備
iOSでは最初からOpenALが利用可能なので、XcodeのプロジェクトのLinked Frameworks and Libraries
にOpenAL.framework
を追加するだけで良いです。
ALUREの準備
いろいろ模索した結果、以下の手順になりました。ただし、ビルド周りは詳しくないので不正確な可能性があります。ご注意を。
- 「ALURE公式サイト」からソースコード一式を入手
- ALUREのビルドにはCMakeが必要なので、まだCMakeを入れていない場合は「CMake公式サイト」からバイナリを入手。dmgを展開してアプリをアプリケーションフォルダなどへ置く。ちなみにCMakeはMakefileを生成するためのツールです。
- 「https://github.com/cristeab/ios-cmake」からCMakeのiOS用ツールチェインファイルを入手します。
- この中の
iOS.cmake
の一部を修正します。(私の環境では修正しないとCMakeの実行に失敗しました)
修正前
include (CMakeForceCompiler) CMAKE_FORCE_C_COMPILER (/usr/bin/gcc Apple) CMAKE_FORCE_CXX_COMPILER (/usr/bin/g++ Apple)
修正後
set(CMAKE_C_COMPILER "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang") set(CMAKE_CXX_COMPILER "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++")
/Applications/CMake.app/Contents/bin/cmake .. -DCMAKE_TOOLCHAIN_FILE=iOS.cmakeのファイルパス
make
を実行。libalure-static.a
などが生成されます。- この
libalure-static.a
を以下のコマンドで中身を展開。(libalure-static.a
ファイルを直接リンクさせてもリンクエラーになりました)
ar -x libalure-static.a
- 展開すると以下のような複数の
.o
ファイルが生成されます。- alure.o
- buffer.o
- codec_aiff.o
- codec_wav.o
- istream.o
- stream.o
- streamdec.o
- streamplay.o
- これらをXcodeのプロジェクトの
Linked Frameworks and Libraries
に追加します。 - Xcodeのプロジェクト設定で
Bitcode
を無効にしておく( ライブラリのビルド時にBitcodeを含めていないのでエラーになる )Build Settings > Build Options > Enable Bitcode
をNo
にする
alure.h
のパスをプロジェクト設定のBuild Settings > Search Paths > User Header Search Paths
などで設定しておく- 生成したALUREライブラリのパスをプロジェクト設定の
Build Settings > Search Paths > Library Search Paths
で設定しておく - Xcodeでビルドします。ビルドが成功したら成功です。
- 実機(iPhoneなど)でちゃんと音が鳴るか確認してみる。
(おまけ)手順を見つけるまでの流れ
上記のような手順になった経緯を参考として残しておきます。
Mac用に生成したALUREライブラリをそのままiOSのプロジェクトに持って行っても当然動きません。まず考えたのがALUREのビルドはCMakeを使っているので、CMakeにiOS用の設定があるんじゃないかということです。探してみたところCMake自体はiOSのビルドに対応していませんでしたが、GithubにiOS用にビルドするためのCMakeファイルがあるのを見つけました。これhttps://github.com/cristeab/ios-cmake です。
このファイルを使えばCMake時に以下のようにオプションとして指定することでiOS用ビルドが可能になるとのこと。
cmake .. -DCMAKE_TOOLCHAIN_FILE=../../../toolchain/iOS.cmake -DIOS_PLATFORM=SIMULATOR
試してみたところ、私の環境ではALUREのCMakeを実行するとエラーが発生しました。
CMake Error at CMakeLists.txt:131 (MESSAGE): PThreads is required for non-Windows builds!
エラーログ(CMakeError.log)の中身を見ると、ライブラリの存在チェック時になぜかiPhoneSDKではなくMacOSX10.11.sdkなどが使われているようす。ぐぬぬ。
いろいろ試してみた結果、iOS.cmakeの以下の場所を修正することでCMakeが成功することがわかりました。
修正前
include (CMakeForceCompiler) CMAKE_FORCE_C_COMPILER (/usr/bin/gcc Apple) CMAKE_FORCE_CXX_COMPILER (/usr/bin/g++ Apple)
修正後
set(CMAKE_C_COMPILER "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang") set(CMAKE_CXX_COMPILER "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++")
この違いがどう違うのかわかりませんが、とにかくこうすることでCMakeが成功するようになりました。ちなみに、CMAKE_FORCE_C_COMPILER
からCMAKE_C_COMPILER
に変えたのは、CMAKE_FORCE_C_COMPILER
が最新のドキュメントで非推奨になっていたからです。https://cmake.org/cmake/help/latest/module/CMakeForceCompiler.html
続いてmake
でビルドします。これは普通に成功し、libalure-static.a
が生成されました。
このlibalure-static.a
をXcodeのiOSのプロジェクトのLinked Frameworks and Libraries
に追加してビルドします。すると以下のような警告とともにリンクエラーが。
ld: warning: ignoring file ***/Lib/libalure-static.a, file was built for archive which is not the architecture being linked (armv7): Undefined symbols for architecture armv7: "_alureGetErrorString", referenced from:
armv7用のシンボルが見つからないと言われているような。
このリンクエラーの対処法の前に、生成されたlibalure-static.a
について状況を確認したいと思います。
このlibalure-static.a
は、内部的には以下のオブジェクトファイルから構成されています。
- alure.o
- buffer.o
- codec_aiff.o
- codec_wav.o
- istream.o
- stream.o
- streamdec.o
- streamplay.o
これはarコマンドを使って確認することができます。例:ar -t libalure-static.a
そしてこれらのそれぞれの.o
ファイルは、armv7
、armv7s
、arm64
の3つのアーキテクチャのバイナリを合体させたFATバイナリ(universal binary)と呼ばれるものになっています。これはfileコマンドで確認することができます。
$ file alure.o alure.o: Mach-O universal binary with 3 architectures alure.o (for architecture armv7): Mach-O object arm alure.o (for architecture armv7s): Mach-O object arm alure.o (for architecture arm64): Mach-O 64-bit object
このようにちゃんとarmv7用のバイナリが含まれているのにリンクエラーになってしまっています。
ちなみに、FATバイナリを作るにはlipoコマンドが必要との情報をみかけましたが、ビルドオプションで-arch armv7 -arch armv7s -arch arm64
のように-arch
オプションを複数設定すれば勝手にFATバイナリにしてくれるようです。CMakeではCMAKE_OSX_ARCHITECTURESコマンドで設定したアーキテクチャがビルド時に-arch
オプションとして渡されるようです。そしてCMAKE_OSX_ARCHITECTURESコマンドはiOS.cmakeによって自動で設定されます。
さて、このリンクエラーを解決するために試しにarコマンドでlibalure-static.a
の中身を展開して、それらをLinked Frameworks and Libraries
に追加してビルドしてみると…ビルドに成功しました。FATバイナリをアーカイブ化したものはダメなのか、それともアーカイブ化の方法が間違っていたのかよくわかりませんが、とにかくリンクエラーを解決する方法が見つかりました。(解決まで丸2日かかりました)
(おまけ)MacでOpenAL+ALUREを使う
ついでにMacでのOpenAL+ALUREの利用方法も紹介しておきます。先にMacでALUREの動作確認をしておくのもいいかもしれません。
OpenALの準備
MacでOpenALを使う場合、OpenALは最初から入っているのでビルドオプションで-framework OpenAL
とするだけで良いです。(もしくはXcodeのプロジェクトのLinked Frameworks and Libraries
にOpenAL.frameworkを追加する)
ALUREの準備
ALUREを利用するには以下の手順が必要になります。
- ALURE公式サイトからソースコード一式を入手
- ALUREのビルドにはCMakeが必要なので、まだCMakeを入れていない場合はCMake公式サイトからバイナリを入手。dmgを展開してアプリをアプリケーションフォルダなどへ置く。ちなみにCMakeはMakefileを生成するためのツールです。
- ターミナルでALUREソースコード一式内のbuildディレクトリに移動し、
/Applications/CMake.app/Contents/bin/cmake ..
を実行。(Makefileが作られる) - そのまま
make
を実行。(ビルドが走りライブラリファイルが生成される) - そのまま
make install
を実行。(ライブラリファイルなどが/usr/local/libなどに配置される) - ビルドオプションで
-lalure
などしてリンクする。(もしくはXcodeのプロジェクトのLinked Frameworks and Libraries
に追加する)
雑に説明しましたがMacでの利用手順はこんな感じです。