1*05767d91SRobert Wu**DrumThumper** 2*05767d91SRobert Wu========== 3*05767d91SRobert WuOboe playback sample app. 4*05767d91SRobert Wu 5*05767d91SRobert Wu## Abstract 6*05767d91SRobert Wu**DrumThumper** is a "Drum Pad" app which demonstrates best-practices for low-latency audio playback using the Android **Oboe** API. 7*05767d91SRobert Wu**DrumThumper** consists of a set of trigger pad widgets and an optional UI for controlling the level and stereo placement of each of the virtual drums. 8*05767d91SRobert WuThe audio samples are stored in application resources as WAV data. This is parsed and loaded (by routines in **parselib**) into memory blocks. 9*05767d91SRobert WuThe audio samples are mixed and played by routines in **iolib**. 10*05767d91SRobert Wu 11*05767d91SRobert Wu**DrumThumper** is written in a combination of Kotlin for the UI and JNI/C++ for the player components (to demonstrate accessing native code from a Kotlin or Java application). 12*05767d91SRobert Wu 13*05767d91SRobert Wu## Scope 14*05767d91SRobert Wu**DrumThumper** is designed with the following goals in mind: 15*05767d91SRobert Wu* To demonstrate the most efficient means of playing audio with the lowest possible latency. 16*05767d91SRobert Wu* To demonstrate how to play multiple sources of audio mixed into a single Oboe stream. 17*05767d91SRobert Wu* To demonstrate the life-cycle of an Oboe audio stream and it's relationship to the application lifecycle. 18*05767d91SRobert Wu* To demonstrate the correct handling of playback errors and output device connection/disconnection. 19*05767d91SRobert Wu 20*05767d91SRobert WuSecondarily, **DrumThumper** demonstrates: 21*05767d91SRobert Wu* Using Android "assets" for audio data. 22*05767d91SRobert Wu* The mechanism for calling native (C/C++) audio functionality from a Kotlin/Java app. 23*05767d91SRobert Wu* A mechanism for sharing binary data between a Kotlin/Java app with the native (C/C++) layer. 24*05767d91SRobert Wu* A mechanism for parsing/loading one type (WAV) of audio data. 25*05767d91SRobert Wu* How to control the relative levels (gain) of audio sources mixed into an output stream. 26*05767d91SRobert Wu* How to locate a mono data source in a stereo output stream. 27*05767d91SRobert Wu* How to use the Oboe resampler to resample source audio to the device playback rate, and therefore not incur this overhead at playback time. 28*05767d91SRobert Wu 29*05767d91SRobert WuTo keep things simple, **DrumThumper** specifically does not: 30*05767d91SRobert Wu* Does not support audio samples in other than 16-bit PCM Samples. It does not support different PCM formats. 31*05767d91SRobert Wu* Does not support non-WAV audio data (such as AIFF). 32*05767d91SRobert Wu* Does not support compressed audio data. 33*05767d91SRobert Wu 34*05767d91SRobert Wu**DrumThumper** now supports different sample rates for the source samples. 35*05767d91SRobert Wu 36*05767d91SRobert Wu**DrumThumper** now supports mono and stereo sources. 37*05767d91SRobert Wu 38*05767d91SRobert Wu## DrumThumper project structure 39*05767d91SRobert Wu### Kotlin App Layer 40*05767d91SRobert WuContains classes for the application logic and defines the methods for accessing the native data and player functionality. 41*05767d91SRobert Wu 42*05767d91SRobert Wu### Native (C++) layer 43*05767d91SRobert WuContains the implementation of the `native` (JNI) methods defined in the `DrumPlayer` (Kotlin) class. 44*05767d91SRobert Wu 45*05767d91SRobert Wu### Dependent Libraries 46*05767d91SRobert Wu* **iolib** 47*05767d91SRobert WuClasses for playing audio data. 48*05767d91SRobert Wu 49*05767d91SRobert Wu* **parselib** 50*05767d91SRobert WuClasses for parsing and loading audio data from WAV resources. 51*05767d91SRobert Wu 52*05767d91SRobert Wu## App 53*05767d91SRobert Wu* DrumPlayer.kt 54*05767d91SRobert WuThe Kotlin class which provides the audio playback functionality by interfacing with the native (C++) libraries. 55*05767d91SRobert Wu 56*05767d91SRobert Wu* DrumThumperActivity.kt 57*05767d91SRobert WuThe main application logic. 58*05767d91SRobert Wu 59*05767d91SRobert Wu* TriggerPad.kt 60*05767d91SRobert WuAn Android View subclass which implements the "trigger pad" UI widgets 61*05767d91SRobert Wu 62*05767d91SRobert Wu## Native-interface (JNI) 63*05767d91SRobert Wu* DrumPlayerJNI.cpp 64*05767d91SRobert Wu This is where all the access to the native functionality is implemented. 65*05767d91SRobert Wu 66*05767d91SRobert Wu## Screenshots 67*05767d91SRobert Wu 68