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
83
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
580
PHPとRustを組み合わせて音声ファイルをエンコードする話
yaminoma
0
4.5k
Other Decks in Programming
See All in Programming
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
480
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
140
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
430
the container ship “Apple Silicon”@WWDC26 Recap -Japan-\(region).swift
shingangan
0
110
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
670
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
140
ソフトウェア設計に溶けるインフラ ― AWS CDK のインフラ認識論
konokenj
3
760
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
860
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.4k
Go 1.27 における memory allocation の高速化
andpad
0
110
仕様駆動開発の消費期限
watany
16
7.3k
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
450
Featured
See All Featured
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
66
57k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
400
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
Everyday Curiosity
cassininazir
0
270
[SF Ruby Conf 2025] Rails X
palkan
2
1.3k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
Facilitating Awesome Meetings
lara
57
7.1k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
610
Mobile First: as difficult as doing things right
swwweet
225
10k
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 ۃݶ·ͰΧελϚΠζ͍ͨ͠ਓຊηογϣϯͷ༰Λࢀ ߟʹɺ࣮ͯ͠Έ͍ͯͩ͘͞ ·ͱΊ