Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
今日から分かる Android Audioの全て
Search
Shumpei Urabe
October 26, 2020
Programming
510
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
今日から分かる Android Audioの全て
KSA Online Meetup #1
https://student-kyushu.connpass.com/event/191541/
Shumpei Urabe
October 26, 2020
More Decks by Shumpei Urabe
See All by Shumpei Urabe
放送局の“SIer依存”は終わるのか? 〜Claude Code・Devin時代のAIネイティブ放送DX〜
yaminoma
0
67
AIを活用した放送技術スタートアップの制作現場改革について
yaminoma
0
16k
動画配信技術について
yaminoma
2
1.8k
Multimedia Security Topics
yaminoma
0
2.6k
コロナ禍でのライブストリーミングの変化とテレビ放送の規格について
yaminoma
0
1.2k
Apple Low-Latency HLSを使った 超低遅延配信について
yaminoma
4
5.3k
今日から分かる AVAudioEngineの全て
yaminoma
4
6.4k
Cross Platform Video Player
yaminoma
0
570
PHPとRustを組み合わせて音声ファイルをエンコードする話
yaminoma
0
4.1k
Other Decks in Programming
See All in Programming
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.8k
地域 SRE コミュニティ最前線 - ホンマでっかSRE勉強会
tk3fftk
0
220
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
130
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
190
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.3k
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.4k
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
どこまでゆるくて許されるのか
tk3fftk
0
470
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
570
Claude Team Plan導入・ガイド
tk3fftk
0
170
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
180
フィードバックで育てるAI開発
kotaminato
1
110
Featured
See All Featured
Navigating Weather and Climate Data
rabernat
0
310
A Tale of Four Properties
chriscoyier
163
24k
The browser strikes back
jonoalderson
0
1.4k
The Cult of Friendly URLs
andyhume
79
6.9k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Tell your own story through comics
letsgokoyo
1
990
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
300
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
Designing for humans not robots
tammielis
254
26k
Writing Fast Ruby
sferik
630
63k
The Pragmatic Product Professional
lauravandoore
37
7.4k
Transcript
ࠓ͔Β͔Δ Android Audioͷશͯ 2020.10.26 ߹ಉձࣾφΫα ෦ ॡฏ
ࣗݾհ ෦ ॡฏ • ߹ಉձࣾφΫαɹද • ΤϯλϝͷϥΠϒ৴Λࢧ͍͑ͯ ·͢ • झຯ࡞ۂͱωοτϫʔΫӡ༻
• Android։ൃͰҰ൪͍ͬͯΔͷ MediaCodecͱVulkan
Pixel 3 w 1JYFMͰɺ""VEJP͕ݪҼͰ࠶ੜ͞Ε ͳ͍͕͋ͬͨ
ձࣾհ 1.
w ݄ʹઃཱ w ຊࣾ౦ژઍా۠ਆాۋொ w ΦϑΟεʹϥοΫ͕͋Δ w ϝϯόʔ໊ w ࠾༻ืूதʂ
߹ಉձࣾφΫα
w &/5&35"*.&/5ʷ5&$)/0-0(: w ΤϯλʔςΠϝϯτͷΛٕज़ΛͬͯղܾΛ͢Δ ձࣾ w Σϒ੍࡞͔Βಈը৴·ͰԿͰΓ·͢ φΫαͷࣄۀ
w ϥΠϒ৴αʔϏε w ిࢠॻ੶αʔϏε w ͳͲͳͲ ࣄۀྫ
w /-*7&ɺφΫα͕ఏڙ͍ͯ͠ΔιϦϡʔγϣϯͷҰͭɻ w /-*7&ɺΫϥΠΞϯτ͔ΒΠϯϑϥ·ͰશͯφΫα͕Χ όʔ͢Δ͜ͱ͕ग़དྷ·͢ w ͦͷଞɺ%3.ͷରԠͳͲαϙʔτ͢Δ͜ͱ͕ՄೳͰ͢ ϥΠϒ৴ιϦϡʔγϣϯ NLIVE
w ڵຯΛ࣋ͬͨਓʹ࿈བྷ͍ͯͩ͘͠͞ w ۀҕୗɾΞϧόΠτେܴͰ͢ We're Hiring!
AndroidͷAudioͷྺ࢙ 2.
w "VEJP'MJOHFS"VEJP4FSWFSͷͭͰ͋ΓɺΞϓϦͷԻΛ ཧ͢Δαʔό w "VEJP'MJOHFS"35 "OESPJE3VOUJNF ্Ͱಈ࡞͢Δ w "VEJP'MJOHFS͔Β)"- )BSEXBSF"CTUSBDU-BZFS
ʹॲ ཧ͞ΕͯɺԻ࠶ੜΛߦ͏ AudioFlinger
w "VEJP'MJOHFS͕"OESPJEͷԆͷ தͰಛʹӨڹ͕େ͖͍ w ͦͷཧ༝"VEJP'MJOHFSͰόοϑΝΛ ࡞Γ͔͢ΒͰ͋Δ AudioFlingerͷ10ms
w "VEJP'MJOHFSͷલʹ)"-͕͋Γɺ )"-͕"-4"ͱΓͱΓΛͯ͠σʔλΛ ૹड৴͢Δ w "-4"ϦϯάόοϑΝΛͬͯɺυϥ Πόʔ͔Β"VEJP'MJOHFSʹૹ͍ͬͯΔ AudioFlingerͷ10ms
w "VEJP'MJOHFSͷޙʹ"VEJP3FDPSE "VEJP5SBDL͕͋Δ w ͪ͜Β#ZUF#VGGFSΛͬͯɺόο ϑΝΛ࡞ͬͯॻ͖ࠐΉॲཧ͕͋Δͷ ͰɺԆ͕͋Δ AudioFlingerͷ10ms
w "VEJP"1*ͷඪ४࣮͕0QFO4-&4 w 0QFO4-&4Λ͏͜ͱͰɺ"VEJP'MJOHFSΑΓԆʹ Ի࠶ੜ͕Ͱ͖Δ OpenSL ES
w 0QFO4-&4ͷɺσόΠεʹΑͬͯඇରԠͳ͜ ͱ͕ଟ͍ʢυϥΠόʔͷඇαϙʔτʣ w ·ͨɺ0QFO4-&4ͷ࣮͔ͳΓεύήοςΟίʔυʹ ͳ͓ͬͯΓɺ࣌ʑෆ҆ఆʹͳΔ͜ͱΑ͋͘Δ OpenSL ES͕͍ʹͳΒͳ͍
w "OESPJEΑΓɺ0QFO4-&4ͷସͱͯ͠""VEJP͕ొ ͨ͠ w ""VEJPͰɺ͜Ε·Ͱ"VEJP'MJOHFSͷϥούʔతͳׂ Λ͍ͯͨ͠0QFO4-&4ͱҧ͍ɺ)"-ʹΞΫηεͰ ͖Δ AAudio
w ""VEJP0QFO4-&4ಉ༷ʹ$ Ͱهड़Λߦ͏ͨΊɺ "35ͷ($֎Ͱ͋ΔʢͦͷͨΊϝϞϦղ์ࣗͰΔඞ ཁ͕͋Δʣ w ""VEJPͰɺ֤ϕϯμʔͱڠྗ͠ɺ҆ఆͯ͠ಈ࡞͢Δ͜ ͱΛࢦͨ͠ AAudio
Implementaion 3.
w (PPHMF͕։ൃͨ͠ϥΠϒϥϦ w 0QFO4-&4ͱ""VEJPͷ૬ޓར༻Λ ߦ͏ͨΊͷϥούʔ w ࣗͰॻ͘ͷ͕ͭΒ͍ਓ0CPFΛ ͏ͱ؆୯ʹهड़Ͱ͖Δ Oboe
w 0QFO4-&4ࠓߋ͏ඞཁͳ͍ͷͰࠓճ""VEJPΛ࣮ ͯ͠Έ·͠ΐ͏ ࣗͰ࣮ͯ͠ΈΔ
dlsymͰAAudioΛಡΈࠐΉ w MJCBBVEJPTP NJO4EL7FSTJPO͔Βೖ ͍ͬͯΔ
InputStreamΛ४උ͢Δ void AAudio_IO::setupInputStream( AAudioStreamBuilder* builder ) { AAudioStreamBuilder_setDeviceId ( builder,
_inputDeviceId ); AAudioStreamBuilder_setSampleRate ( builder, _sampleRate ); AAudioStreamBuilder_setChannelCount( builder, _inputChannelCount ); AAudioStreamBuilder_setFormat ( builder, _sampleFormat ); AAudioStreamBuilder_setSharingMode ( builder, AAUDIO_SHARING_MODE_EXCLUSIVE ); AAudioStreamBuilder_setPerformanceMode( builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY ); AAudioStreamBuilder_setDirection ( builder, AAUDIO_DIRECTION_INPUT ); AAudioStreamBuilder_setErrorCallback ( builder, ::errorCallback, this ); }
outputStreamΛ४උ͢Δ void AAudio_IO::setupOutputStream( AAudioStreamBuilder* builder ) { AAudioStreamBuilder_setDeviceId ( builder,
_outputDeviceId ); AAudioStreamBuilder_setFormat ( builder, _sampleFormat ); AAudioStreamBuilder_setChannelCount( builder, _outputChannelCount ); AAudioStreamBuilder_setSharingMode ( builder, AAUDIO_SHARING_MODE_EXCLUSIVE ); AAudioStreamBuilder_setPerformanceMode( builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY ); AAudioStreamBuilder_setDirection ( builder, AAUDIO_DIRECTION_OUTPUT ); AAudioStreamBuilder_setDataCallback ( builder, ::dataCallback, this ); AAudioStreamBuilder_setErrorCallback ( builder, ::errorCallback, this ); }
inputStreamΛ࡞Δ void AAudio_IO::createInputStream() { AAudioStreamBuilder* builder = createStreamBuilder(); setupInputStream( builder
); aaudio_result_t result = static_cast<aaudio_result_t>(AAudioStreamBuilder_openStream( builder, &_inputStream )); AAudioStreamBuilder_delete( builder ); }
outputStreamΛ࡞Δ void AAudio_IO::createOutputStream() { AAudioStreamBuilder* builder = createStreamBuilder(); setupOutputStream( builder
); aaudio_result_t result = static_cast<aaudio_result_t>(AAudioStreamBuilder_openStream( builder, &_outputStream )); if ( result == AAUDIO_OK && _outputStream != nullptr ) { _sampleRate = AAudioStream_getSampleRate( _outputStream ); _framesPerBurst = AAudioStream_getFramesPerBurst( _outputStream ); AudioEngineProps::SAMPLE_RATE = _sampleRate; updateBufferSizeInFrames( AAudioStream_setBufferSizeInFrames( _outputStream, _framesPerBurst )); _underrunCountOutputStream = AAudioStream_getXRunCount( _outputStream ); } else { return; } AAudioStreamBuilder_delete( builder ); }
streamΛ։࢝ɾఀࢭ͢Δ void AAudio_IO::startStream( AAudioStream* stream ) { aaudio_result_t result =
static_cast<aaudio_result_t>(AAudioStream_requestStart( stream )); if ( result != AAUDIO_OK ) { return; } } void AAudio_IO::stopStream( AAudioStream* stream ) { if ( stream == nullptr ) { return; } aaudio_result_t result = static_cast<aaudio_result_t>(AAudioStream_requestStop( stream )); }
w ""VEJP4USFBN#
[email protected]
Ͱɺ-08@-"5&/$:ʹઃఆ͢ΔͱԆʹͳΔ͕ όοςϦʔ͕ݮΔɻ͔͠ɺ͜Ε͚ͩͩͱ͋·Γҙຯ͕ͳ͍ʢޙड़ʣ w ""VEJP5ISFBE4BGFͰͳ͍ɻͦͷͨΊɺผεϨου͔Βಉ࣌ʹ""VEJPΛݺͼग़͢͜ͱͰ͖ͳ ͍ɻ w ίʔϧόοΫؔΛ͍ɺඇಉظͰॲཧΛ͢Δ͜ͱΛਪɻ४උ͕Ͱ͖ͨΒίʔϧόοΫͰಡΈࠐΈɾ ॻ͖ࠐΈ͕Ͱ͖Δɻ w
όοϑΝαΠζΛௐ͢Δ͖ɻ࠷ॳ5$1ͷ8JOEPX4J[F0QUJNJ[FͷΑ͏ʹঃʑʹόοϑΝαΠ ζΛେ͖͍ͯ͘͘͠ํ͕Α͍ɻ AAudioͷͭ·͖ͮϙΠϯτ
w ""VEJPͷ-PX-BUFODZ.PEF͚ͩͩͱԆʹͳΒͳ͍ w "DUJWJUZͷ8JOEPX.BOBHFSʹ8JOEPX.BOBHFS-BZPVU1BSBNT'-"(@,&&1@4$3&&/@0/Λ ηοτ͢Δඞཁ͕͋Δ w BDUJWJUZHFU8JOEPX TFU4VTUBJOFE1FSGPSNBODF.PEF USVF ͰɺύϑΥʔϚϯεϞʔυΛ༗ޮʹ
͢Δ WindowManagerΛϋοΫ͢Δ
inline void optimizeThreadPerformance( const std::vector<int>& cpuIds ) { cpu_set_t mask;
pid_t current_thread_id = gettid(); cpu_set_t cpu_set; CPU_ZERO( &cpu_set ); if ( cpuIds.empty() ) { int current_cpu_id = sched_getcpu(); CPU_SET( current_cpu_id, &cpu_set ); } else { for ( size_t i = 0; i < cpuIds.size(); i++ ) { int cpu_id = cpuIds.at( i ); CPU_SET( cpu_id, &cpu_set ); } } } CPUΞϑΟχςΟΛεϨουʹઃఆ͢Δ w ΞϑΟχςΟΛઃఆ͢Δ͜ͱͰɺ$16ύϑΥʔ ϚϯεΛۃݶ·Ͱ্ͤ͞Δ͜ͱ͕Ͱ͖Δ w ϓϩηεɾεϨου04ʹΑͬͯͲΕ͔ͷ $16ίΞ্Ͱ࣮ߦ͞ΕΔɻ$16ΞϑΟχςΟΛ ઃఆ͢Δ͜ͱͰɺͦͷ࣮ߦ͞ΕΔ$16ίΞΛ ҙʹ੍ݶɾࢦఆ͢Δ͜ͱ͕Ͱ͖Δɻ
·ͱΊ 4.
w "OESPJEͷΦʔσΟΦͷྺ࢙͘ɺෳࡶͰ͋Δ w 0CPFΛͱΓ͓͚͋͑ͣͬͯΑ͍ w ۃݶ·ͰΧελϚΠζ͍ͨ͠ਓຊηογϣϯͷ༰Λࢀ ߟʹɺ࣮ͯ͠Έ͍ͯͩ͘͞ ·ͱΊ