SlideShare a Scribd company logo
/// A tiny value that can be easily transferred acoustically between devices.
public struct Token {
public let value: UInt16
/// create a token from an unsigned 16-bit quantity
public init(_ value: UInt16)
/// create a token from 16 bits with the most-significant-bit first
public init(bigEndianBits bits: [Bit])
/// extract the bits in most-significant-bit-first order
internal var bigEndianBits: [Bit] { get }
}
Protocol (1/2)
/// a more concise name for the pointer to buffers of our audio data
typealias FloatBuffer = UnsafeMutablePointer<Float>
// protocol parameters
let sampleRate: Float = 44100 // samples per second
let baseFreq: Float = 843.8 // hertz
let fftLength: Int = 4096
let toneBinStride: Int = 8
// derived constants
let firstToneBin = hz2bin(Float(baseFreq))
let freqSpacing = bin2hz(firstToneBin + toneBinStride) - bin2hz(firstToneBin)
let lastToneBin = firstToneBin + ((Token.numBits-1) * toneBinStride)
let toneBins = firstToneBin.stride(through: lastToneBin, by: toneBinStride)
Protocol (2/2)
/// generates a buffer of 32-bit float audio samples where the
/// provided `token` is encoded in the frequency domain
/// according to the "audio barcode" protocol.
func encode(token: Token, buffer: FloatBuffer, numSamples: Int) {
// generate a tone for each bit that is turned on
for (i, bit) in token.bigEndianBits.enumerate()
where bit == .One {
let freq = baseFreq + (Float(i) * freqSpacing)
tone(Float(freq), buffer: buffer, numSamples: numSamples)
}
}
Transmit (1/4)
/// mixes a tone with frequency 'hz' into 'buffer'
private func tone(hz: Float, buffer: FloatBuffer, numSamples: Int) {
let x = twoPi * hz / sampleRate
for i in 0..<numSamples {
buffer[i] += sinf(Float(i) * x)
}
}
Transmit (2/4)
Transmit (3/4)
self.engine = AVAudioEngine()
self.toneGen = AVAudioPlayerNode()
self.engine.attachNode(self.toneGen)
self.audioFormat = AVAudioFormat(standardFormatWithSampleRate:
Double(sampleRate), channels: 1)
self.engine.connect(self.toneGen,
to: self.engine.outputNode,
format: self.audioFormat)
try! AVAudioSession.sharedInstance()
.setCategory(AVAudioSessionCategoryPlayAndRecord)
try! engine.start()
Transmit (4/4)
let pcmBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat,
frameCapacity: AVAudioFrameCount(10 * sampleRate))
let bufferRaw = pcmBuffer.floatChannelData[0]
let numFrames = Int(pcmBuffer.frameCapacity)
encode(token, buffer: bufferRaw, numSamples: numFrames)
pcmBuffer.frameLength = AVAudioFrameCount(numFrames)
toneGen.scheduleBuffer(pcmBuffer, atTime: nil, options: .Loops) {
print("buffer finished playing")
}
toneGen.play()
Receive (1/4)
let desiredBufferSize = AVAudioFrameCount(1 * sampleRate)
inputNode.installTapOnBus(0, bufferSize: desiredBufferSize, format: nil) {
pcmBuffer, time in
let rawBuffer = pcmBuffer.floatChannelData[0]
if let token = decode(rawBuffer, numSamples: fftLength) {
print("got token", token)
}
}
func decode(inputSamples: FloatBuffer, numSamples: Int) -> Token? {
// ...snip... allocate raw memory
// de-interleave to get the audio input into the format that vDSP wants
let (evenSamples, oddSamples) = deinterleave(inputSamples, inputLength: fftLength)
// perform the DFT
vDSP_DFT_Execute(setup, evenSamples, oddSamples, outReal, outImaginary)
// compute magnitudes for each frequency bin (convert from complex to real)
var freqComplex = DSPSplitComplex(realp: outReal, imagp: outImaginary)
vDSP_zvmags(&freqComplex, 1, freqMagnitudes, 1, vDSP_Length(fftLength/2))
// analyze
let token = decodeStage2(freqMagnitudes, numMagnitudes: fftLength/2)
// ...snip... cleanup raw memory
return token
}
Receive (2/4)
private func decodeStage2(magnitudes: FloatBuffer, numMagnitudes: Int) -> Token? {
// estimate the noise floor by using the magnitude in nearby bins
let preBins = [firstToneBin-7, firstToneBin-6, firstToneBin-5]
let postBins = [lastToneBin+5, lastToneBin+6, lastToneBin+7]
let noiseFloor = (preBins + postBins)
.map { magnitudes[$0] }
.mean()
// find the magnitude of the tallest peak
var peak: Float = 0.0
for bin in toneBins {
peak = max(peak, magnitudes[bin])
}
// ... continued on next slide
Receive (3/4)
// ... continued from decodeStage2 on prev slide
// bail out early if the signal isn't strong enough
if peak/noiseFloor < 5.0 {
return nil
}
// set the hard-decision threshold to be above the noise floor
// but also not too high that it would reject weak tones
let threshold = (0.1 * (peak - noiseFloor)) + noiseFloor
// decide which tones are present and which are not
var bits = [Bit]()
for bin in toneBins {
let magnitude = magnitudes[bin]
let isOn = magnitude > threshold
bits.append(isOn ? .One : .Zero)
}
return Token(bigEndianBits: bits)
}
Receive (4/4)
https://github.com/klazuka/CotapTechTalk
Source code and demo app
Contact info
klazuka@gmail.com
Recommended DSP Book
Understanding Digital Signal Processing
by Richard G. Lyons

More Related Content

What's hot

[PDF] 2021 Termux basic commands list
[PDF] 2021 Termux basic commands list [PDF] 2021 Termux basic commands list
[PDF] 2021 Termux basic commands list
nisivaasdfghj
 
Go concurrency
Go concurrencyGo concurrency
Go concurrency
siuyin
 
Linux Commands
Linux CommandsLinux Commands
Linux Commands
lucita cabral
 
#2 (UDP)
#2 (UDP)#2 (UDP)
#2 (UDP)
Ghadeer AlHasan
 
Termux commands-list
Termux commands-listTermux commands-list
Termux commands-list
DhanushR24
 
Linux Commands - Cheat Sheet
Linux Commands - Cheat Sheet Linux Commands - Cheat Sheet
Linux Commands - Cheat Sheet
Isham Rashik
 
TLPI - Chapter 44 Pipe and Fifos
TLPI - Chapter 44 Pipe and FifosTLPI - Chapter 44 Pipe and Fifos
TLPI - Chapter 44 Pipe and FifosShu-Yu Fu
 
GoLightly: A Go Library For Building Virtual Machines
GoLightly: A Go Library For Building Virtual MachinesGoLightly: A Go Library For Building Virtual Machines
GoLightly: A Go Library For Building Virtual Machines
Eleanor McHugh
 
Unix Programming with Perl 2
Unix Programming with Perl 2Unix Programming with Perl 2
Unix Programming with Perl 2
Kazuho Oku
 
Java 7 - short intro to NIO.2
Java 7 - short intro to NIO.2Java 7 - short intro to NIO.2
Java 7 - short intro to NIO.2
Martijn Verburg
 
Metasploit cheat sheet
Metasploit cheat sheetMetasploit cheat sheet
Metasploit cheat sheethughpearse
 
Using the Power to Prove
Using the Power to ProveUsing the Power to Prove
Using the Power to Prove
Kazuho Oku
 
Exploitation of counter overflows in the Linux kernel
Exploitation of counter overflows in the Linux kernelExploitation of counter overflows in the Linux kernel
Exploitation of counter overflows in the Linux kernel
Vitaly Nikolenko
 
The async/await concurrency pattern in Golang
The async/await concurrency pattern in GolangThe async/await concurrency pattern in Golang
The async/await concurrency pattern in Golang
Matteo Madeddu
 
Unix Programming with Perl
Unix Programming with PerlUnix Programming with Perl
Unix Programming with PerlKazuho Oku
 
Go on!
Go on!Go on!
Go on!
Vadim Petrov
 
Sockets intro
Sockets introSockets intro
Sockets intro
AviNash ChaVhan
 
Introduction to rust
Introduction to rustIntroduction to rust
Introduction to rust
mysangle
 
Rust言語紹介
Rust言語紹介Rust言語紹介
Rust言語紹介
Paweł Rusin
 
agri inventory - nouka data collector / yaoya data convertor
agri inventory - nouka data collector / yaoya data convertoragri inventory - nouka data collector / yaoya data convertor
agri inventory - nouka data collector / yaoya data convertor
Toshiaki Baba
 

What's hot (20)

[PDF] 2021 Termux basic commands list
[PDF] 2021 Termux basic commands list [PDF] 2021 Termux basic commands list
[PDF] 2021 Termux basic commands list
 
Go concurrency
Go concurrencyGo concurrency
Go concurrency
 
Linux Commands
Linux CommandsLinux Commands
Linux Commands
 
#2 (UDP)
#2 (UDP)#2 (UDP)
#2 (UDP)
 
Termux commands-list
Termux commands-listTermux commands-list
Termux commands-list
 
Linux Commands - Cheat Sheet
Linux Commands - Cheat Sheet Linux Commands - Cheat Sheet
Linux Commands - Cheat Sheet
 
TLPI - Chapter 44 Pipe and Fifos
TLPI - Chapter 44 Pipe and FifosTLPI - Chapter 44 Pipe and Fifos
TLPI - Chapter 44 Pipe and Fifos
 
GoLightly: A Go Library For Building Virtual Machines
GoLightly: A Go Library For Building Virtual MachinesGoLightly: A Go Library For Building Virtual Machines
GoLightly: A Go Library For Building Virtual Machines
 
Unix Programming with Perl 2
Unix Programming with Perl 2Unix Programming with Perl 2
Unix Programming with Perl 2
 
Java 7 - short intro to NIO.2
Java 7 - short intro to NIO.2Java 7 - short intro to NIO.2
Java 7 - short intro to NIO.2
 
Metasploit cheat sheet
Metasploit cheat sheetMetasploit cheat sheet
Metasploit cheat sheet
 
Using the Power to Prove
Using the Power to ProveUsing the Power to Prove
Using the Power to Prove
 
Exploitation of counter overflows in the Linux kernel
Exploitation of counter overflows in the Linux kernelExploitation of counter overflows in the Linux kernel
Exploitation of counter overflows in the Linux kernel
 
The async/await concurrency pattern in Golang
The async/await concurrency pattern in GolangThe async/await concurrency pattern in Golang
The async/await concurrency pattern in Golang
 
Unix Programming with Perl
Unix Programming with PerlUnix Programming with Perl
Unix Programming with Perl
 
Go on!
Go on!Go on!
Go on!
 
Sockets intro
Sockets introSockets intro
Sockets intro
 
Introduction to rust
Introduction to rustIntroduction to rust
Introduction to rust
 
Rust言語紹介
Rust言語紹介Rust言語紹介
Rust言語紹介
 
agri inventory - nouka data collector / yaoya data convertor
agri inventory - nouka data collector / yaoya data convertoragri inventory - nouka data collector / yaoya data convertor
agri inventory - nouka data collector / yaoya data convertor
 

Viewers also liked

Analisis budpop
Analisis budpopAnalisis budpop
Analisis budpop
ociHmI
 
presentation critical discourse analysis Fairclough
presentation critical discourse analysis Faircloughpresentation critical discourse analysis Fairclough
presentation critical discourse analysis Fairclough
Tri Sulis
 
Linguistik trapan analisis semiotika
Linguistik trapan analisis semiotikaLinguistik trapan analisis semiotika
Linguistik trapan analisis semiotikaRiska sasaka
 
Strukturalisme dan Semiotik
Strukturalisme dan SemiotikStrukturalisme dan Semiotik
Strukturalisme dan Semiotik
Shafira Rahmani
 
Analisis Wacana Kritis
Analisis Wacana KritisAnalisis Wacana Kritis
Analisis Wacana Kritis
hakim jayli
 
bahasa Indonesia kelas XII
bahasa Indonesia kelas XII bahasa Indonesia kelas XII
bahasa Indonesia kelas XII Yusuf AL-Rosyadi
 
Peta konsep sms6
Peta konsep sms6Peta konsep sms6
Peta konsep sms6
Paulus Parwira
 

Viewers also liked (8)

Analisis budpop
Analisis budpopAnalisis budpop
Analisis budpop
 
presentation critical discourse analysis Fairclough
presentation critical discourse analysis Faircloughpresentation critical discourse analysis Fairclough
presentation critical discourse analysis Fairclough
 
Linguistik trapan analisis semiotika
Linguistik trapan analisis semiotikaLinguistik trapan analisis semiotika
Linguistik trapan analisis semiotika
 
Analisis wacana
Analisis wacanaAnalisis wacana
Analisis wacana
 
Strukturalisme dan Semiotik
Strukturalisme dan SemiotikStrukturalisme dan Semiotik
Strukturalisme dan Semiotik
 
Analisis Wacana Kritis
Analisis Wacana KritisAnalisis Wacana Kritis
Analisis Wacana Kritis
 
bahasa Indonesia kelas XII
bahasa Indonesia kelas XII bahasa Indonesia kelas XII
bahasa Indonesia kelas XII
 
Peta konsep sms6
Peta konsep sms6Peta konsep sms6
Peta konsep sms6
 

Similar to Cotap Tech Talks: Keith Lazuka, Digital Communication using Sound and Swift

Sysprog17
Sysprog17Sysprog17
Sysprog17
Ahmed Mekkawy
 
4Developers 2018: The turbulent road to byte-addressable storage support at t...
4Developers 2018: The turbulent road to byte-addressable storage support at t...4Developers 2018: The turbulent road to byte-addressable storage support at t...
4Developers 2018: The turbulent road to byte-addressable storage support at t...
PROIDEA
 
Apache Flink Training: DataStream API Part 1 Basic
 Apache Flink Training: DataStream API Part 1 Basic Apache Flink Training: DataStream API Part 1 Basic
Apache Flink Training: DataStream API Part 1 Basic
Flink Forward
 
Visual Studio C++ OOP I need to complete the program about how to .pdf
Visual Studio C++ OOP I need to complete the program about how to .pdfVisual Studio C++ OOP I need to complete the program about how to .pdf
Visual Studio C++ OOP I need to complete the program about how to .pdf
amanbag
 
What Shazam doesn't want you to know
What Shazam doesn't want you to knowWhat Shazam doesn't want you to know
What Shazam doesn't want you to know
Roy van Rijn
 
How to develop a rich terminal UI application
How to develop a rich terminal UI applicationHow to develop a rich terminal UI application
How to develop a rich terminal UI application
Masashi Shibata
 
GNU Radio
GNU RadioGNU Radio
GNU Radio
milowenwen
 
Linux Systems Programming: Inter Process Communication (IPC) using Pipes
Linux Systems Programming: Inter Process Communication (IPC) using PipesLinux Systems Programming: Inter Process Communication (IPC) using Pipes
Linux Systems Programming: Inter Process Communication (IPC) using Pipes
RashidFaridChishti
 
Openframworks x Mobile
Openframworks x MobileOpenframworks x Mobile
Openframworks x Mobile
Janet Huang
 
Tutorial of SF-TAP Flow Abstractor
Tutorial of SF-TAP Flow AbstractorTutorial of SF-TAP Flow Abstractor
Tutorial of SF-TAP Flow Abstractor
Yuuki Takano
 
IL: 失われたプロトコル
IL: 失われたプロトコルIL: 失われたプロトコル
IL: 失われたプロトコル
Ryousei Takano
 
TinyML - 4 speech recognition
TinyML - 4 speech recognition TinyML - 4 speech recognition
TinyML - 4 speech recognition
艾鍗科技
 
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Codemotion
 
Inter process communication
Inter process communicationInter process communication
Inter process communicationPradeep Kumar TS
 
Netty: asynchronous data transfer
Netty: asynchronous data transferNetty: asynchronous data transfer
Netty: asynchronous data transfer
Victor Cherkassky
 
Gunosy.go #4 go
Gunosy.go #4 goGunosy.go #4 go
Gunosy.go #4 go
Taku Fukushima
 
Things wrong with my code- 1- The notes do not play when i press down.pdf
Things wrong with my code- 1- The notes do not play when i press down.pdfThings wrong with my code- 1- The notes do not play when i press down.pdf
Things wrong with my code- 1- The notes do not play when i press down.pdf
EricvtJFraserr
 
sockets_intro.ppt
sockets_intro.pptsockets_intro.ppt
sockets_intro.ppt
AnilGupta681764
 

Similar to Cotap Tech Talks: Keith Lazuka, Digital Communication using Sound and Swift (20)

Sysprog17
Sysprog17Sysprog17
Sysprog17
 
4Developers 2018: The turbulent road to byte-addressable storage support at t...
4Developers 2018: The turbulent road to byte-addressable storage support at t...4Developers 2018: The turbulent road to byte-addressable storage support at t...
4Developers 2018: The turbulent road to byte-addressable storage support at t...
 
Apache Flink Training: DataStream API Part 1 Basic
 Apache Flink Training: DataStream API Part 1 Basic Apache Flink Training: DataStream API Part 1 Basic
Apache Flink Training: DataStream API Part 1 Basic
 
Visual Studio C++ OOP I need to complete the program about how to .pdf
Visual Studio C++ OOP I need to complete the program about how to .pdfVisual Studio C++ OOP I need to complete the program about how to .pdf
Visual Studio C++ OOP I need to complete the program about how to .pdf
 
What Shazam doesn't want you to know
What Shazam doesn't want you to knowWhat Shazam doesn't want you to know
What Shazam doesn't want you to know
 
How to develop a rich terminal UI application
How to develop a rich terminal UI applicationHow to develop a rich terminal UI application
How to develop a rich terminal UI application
 
GNU Radio
GNU RadioGNU Radio
GNU Radio
 
Linux Systems Programming: Inter Process Communication (IPC) using Pipes
Linux Systems Programming: Inter Process Communication (IPC) using PipesLinux Systems Programming: Inter Process Communication (IPC) using Pipes
Linux Systems Programming: Inter Process Communication (IPC) using Pipes
 
Openframworks x Mobile
Openframworks x MobileOpenframworks x Mobile
Openframworks x Mobile
 
Tutorial of SF-TAP Flow Abstractor
Tutorial of SF-TAP Flow AbstractorTutorial of SF-TAP Flow Abstractor
Tutorial of SF-TAP Flow Abstractor
 
Sysprog 16
Sysprog 16Sysprog 16
Sysprog 16
 
IL: 失われたプロトコル
IL: 失われたプロトコルIL: 失われたプロトコル
IL: 失われたプロトコル
 
TinyML - 4 speech recognition
TinyML - 4 speech recognition TinyML - 4 speech recognition
TinyML - 4 speech recognition
 
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
 
Inter process communication
Inter process communicationInter process communication
Inter process communication
 
Netty: asynchronous data transfer
Netty: asynchronous data transferNetty: asynchronous data transfer
Netty: asynchronous data transfer
 
Gunosy.go #4 go
Gunosy.go #4 goGunosy.go #4 go
Gunosy.go #4 go
 
Things wrong with my code- 1- The notes do not play when i press down.pdf
Things wrong with my code- 1- The notes do not play when i press down.pdfThings wrong with my code- 1- The notes do not play when i press down.pdf
Things wrong with my code- 1- The notes do not play when i press down.pdf
 
Basic socket programming
Basic socket programmingBasic socket programming
Basic socket programming
 
sockets_intro.ppt
sockets_intro.pptsockets_intro.ppt
sockets_intro.ppt
 

Recently uploaded

Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Jay Das
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
Tendenci - The Open Source AMS (Association Management Software)
 

Recently uploaded (20)

Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 

Cotap Tech Talks: Keith Lazuka, Digital Communication using Sound and Swift

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12. /// A tiny value that can be easily transferred acoustically between devices. public struct Token { public let value: UInt16 /// create a token from an unsigned 16-bit quantity public init(_ value: UInt16) /// create a token from 16 bits with the most-significant-bit first public init(bigEndianBits bits: [Bit]) /// extract the bits in most-significant-bit-first order internal var bigEndianBits: [Bit] { get } } Protocol (1/2)
  • 13. /// a more concise name for the pointer to buffers of our audio data typealias FloatBuffer = UnsafeMutablePointer<Float> // protocol parameters let sampleRate: Float = 44100 // samples per second let baseFreq: Float = 843.8 // hertz let fftLength: Int = 4096 let toneBinStride: Int = 8 // derived constants let firstToneBin = hz2bin(Float(baseFreq)) let freqSpacing = bin2hz(firstToneBin + toneBinStride) - bin2hz(firstToneBin) let lastToneBin = firstToneBin + ((Token.numBits-1) * toneBinStride) let toneBins = firstToneBin.stride(through: lastToneBin, by: toneBinStride) Protocol (2/2)
  • 14.
  • 15. /// generates a buffer of 32-bit float audio samples where the /// provided `token` is encoded in the frequency domain /// according to the "audio barcode" protocol. func encode(token: Token, buffer: FloatBuffer, numSamples: Int) { // generate a tone for each bit that is turned on for (i, bit) in token.bigEndianBits.enumerate() where bit == .One { let freq = baseFreq + (Float(i) * freqSpacing) tone(Float(freq), buffer: buffer, numSamples: numSamples) } } Transmit (1/4)
  • 16. /// mixes a tone with frequency 'hz' into 'buffer' private func tone(hz: Float, buffer: FloatBuffer, numSamples: Int) { let x = twoPi * hz / sampleRate for i in 0..<numSamples { buffer[i] += sinf(Float(i) * x) } } Transmit (2/4)
  • 17. Transmit (3/4) self.engine = AVAudioEngine() self.toneGen = AVAudioPlayerNode() self.engine.attachNode(self.toneGen) self.audioFormat = AVAudioFormat(standardFormatWithSampleRate: Double(sampleRate), channels: 1) self.engine.connect(self.toneGen, to: self.engine.outputNode, format: self.audioFormat) try! AVAudioSession.sharedInstance() .setCategory(AVAudioSessionCategoryPlayAndRecord) try! engine.start()
  • 18. Transmit (4/4) let pcmBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat, frameCapacity: AVAudioFrameCount(10 * sampleRate)) let bufferRaw = pcmBuffer.floatChannelData[0] let numFrames = Int(pcmBuffer.frameCapacity) encode(token, buffer: bufferRaw, numSamples: numFrames) pcmBuffer.frameLength = AVAudioFrameCount(numFrames) toneGen.scheduleBuffer(pcmBuffer, atTime: nil, options: .Loops) { print("buffer finished playing") } toneGen.play()
  • 19.
  • 20. Receive (1/4) let desiredBufferSize = AVAudioFrameCount(1 * sampleRate) inputNode.installTapOnBus(0, bufferSize: desiredBufferSize, format: nil) { pcmBuffer, time in let rawBuffer = pcmBuffer.floatChannelData[0] if let token = decode(rawBuffer, numSamples: fftLength) { print("got token", token) } }
  • 21. func decode(inputSamples: FloatBuffer, numSamples: Int) -> Token? { // ...snip... allocate raw memory // de-interleave to get the audio input into the format that vDSP wants let (evenSamples, oddSamples) = deinterleave(inputSamples, inputLength: fftLength) // perform the DFT vDSP_DFT_Execute(setup, evenSamples, oddSamples, outReal, outImaginary) // compute magnitudes for each frequency bin (convert from complex to real) var freqComplex = DSPSplitComplex(realp: outReal, imagp: outImaginary) vDSP_zvmags(&freqComplex, 1, freqMagnitudes, 1, vDSP_Length(fftLength/2)) // analyze let token = decodeStage2(freqMagnitudes, numMagnitudes: fftLength/2) // ...snip... cleanup raw memory return token } Receive (2/4)
  • 22. private func decodeStage2(magnitudes: FloatBuffer, numMagnitudes: Int) -> Token? { // estimate the noise floor by using the magnitude in nearby bins let preBins = [firstToneBin-7, firstToneBin-6, firstToneBin-5] let postBins = [lastToneBin+5, lastToneBin+6, lastToneBin+7] let noiseFloor = (preBins + postBins) .map { magnitudes[$0] } .mean() // find the magnitude of the tallest peak var peak: Float = 0.0 for bin in toneBins { peak = max(peak, magnitudes[bin]) } // ... continued on next slide Receive (3/4)
  • 23. // ... continued from decodeStage2 on prev slide // bail out early if the signal isn't strong enough if peak/noiseFloor < 5.0 { return nil } // set the hard-decision threshold to be above the noise floor // but also not too high that it would reject weak tones let threshold = (0.1 * (peak - noiseFloor)) + noiseFloor // decide which tones are present and which are not var bits = [Bit]() for bin in toneBins { let magnitude = magnitudes[bin] let isOn = magnitude > threshold bits.append(isOn ? .One : .Zero) } return Token(bigEndianBits: bits) } Receive (4/4)
  • 24.
  • 25. https://github.com/klazuka/CotapTechTalk Source code and demo app Contact info klazuka@gmail.com Recommended DSP Book Understanding Digital Signal Processing by Richard G. Lyons