android


Generate audio graph from 3gpp


I'm writing audio recorder as part of application which has audio graph as well. For recording and showing live audio graph it was pretty easy, just call MediaRecorder.GetMaxAmplitude() every X ms and based on that update canvas which represents the audio graph.
The problem - I want to have same audio graph when one of the recording is opened, so now I can't use .GetMaxAmplitude() method since I would need to fully play the recording to generate the graph, which would take too much time and is just silly.
If recording output would be .wav, it would be pretty straightforward, lots of material out where how to do it, however MediaRecorder doesn't support .wav and I don't really want embed full ffmpeg with wrapper to my app just for this small functionality to decode 3gpp into wav.
What are my options here?
Using MediaExtractor and MediaCodec you can decode your 3gp (or any other supported mime type) into a series of PCM-16bit (mime audio/raw) buffers and from that you can subsample to obtain your desired amplitude graph at a "graphable" sampling rate.
This is an example using synchronous processing on the input/output buffer so run it on non-UI thread.
Synchronous PCM-16bit MediaCodec Example:
var file = new Java.IO.File(Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDownloads), "someaudiofile.mp3");
if (file.CanRead())
{
var mediaExtractor = new MediaExtractor();
mediaExtractor.SetDataSource(file.ToString());
mediaExtractor.SelectTrack(0); // which track? lets assume single/mono for this example
var mediaFormat = mediaExtractor.GetTrackFormat(0);
var mime = mediaFormat.GetString(MediaFormat.KeyMime);
var mediaCodec = MediaCodec.CreateDecoderByType(mime);
mediaCodec.Configure(mediaFormat, null, null, MediaCodecConfigFlags.None);
mediaCodec.Start();
var bufferInfo = new MediaCodec.BufferInfo();
var inputDone = false;
while (true)
{
if (!inputDone) // process input stream and queue it up for output processing
{
int inputBufferIndex = mediaCodec.DequeueInputBuffer(10000);
if (inputBufferIndex >= 0)
{
var inputBuffer = mediaCodec.GetInputBuffer(inputBufferIndex);
int chunkSize = mediaExtractor.ReadSampleData(inputBuffer, 0);
Log.Debug("SO", $"Input Buffer: {inputBufferIndex}");
if (chunkSize <= 0)
{
mediaCodec.QueueInputBuffer(inputBufferIndex, 0, 0, 0L, MediaCodecBufferFlags.EndOfStream);
inputDone = true;
}
else
{
mediaCodec.QueueInputBuffer(inputBufferIndex, 0, chunkSize, mediaExtractor.SampleTime, MediaCodecBufferFlags.None);
mediaExtractor.Advance();
}
}
}
int outputBufferIndex = mediaCodec.DequeueOutputBuffer(bufferInfo, 1000000);
if (outputBufferIndex >= 0)
{
Log.Debug("SO", $"Output Buffer: {outputBufferIndex}");
if (bufferInfo.Size != 0)
{
var outputBuffer = mediaCodec.GetOutputBuffer(outputBufferIndex); // PCM 16-bit output
var outpuFormat = mediaCodec.GetOutputFormat(outputBufferIndex);
outputBuffer.Position(0);
// !!! Sub-sample the buffer based upon your needed sampling rate for display
var pcm16bitBuffer = outputBuffer.AsShortBuffer();
while (pcm16bitBuffer.HasRemaining)
{
var x = pcm16bitBuffer.Get();
// store the prior values and avg./max/... them for later display based upon some subsampling rate
}
pcm16bitBuffer.Dispose();
mediaCodec.ReleaseOutputBuffer(outputBufferIndex, false);
if (bufferInfo.Flags.HasFlag(MediaCodecBufferFlags.EndOfStream))
break;
}
else
break;
}
else if (outputBufferIndex == -2)
{
Log.Debug("SO", "Output buffer is not available yet, feed more input");
}
}
mediaCodec.Stop();
mediaCodec.Release();
}
Note: There are asynchronous methods available also, consult the MediaCodec docs for Android API levels for what is available for your app's targeted audience.
Output sample using the above method:
Re: MediaCodec

Related Links

Processing-Android boilderplate for correct app start/suspend/resume
Username variable isn't casted to Firebase Database
How to Height of a transparent softkeys bar and transparent status bar?
Convertion of Base64 String to Bitmap returns null
Android studio LibGDX Dependancy issue
How to add text and icon to Android button center it?
(Android-O) App not listed in 'apps with usage access' but is in Nougat
Android ListView with Custom Adapter, slow loading
How to prevent navigation drawer hamburger from changing to arrow [duplicate]
Android Data Binding pass arguments to onClick with lambda expression
Android TV: PlaybackControlsRow action long press
Delete incoming SMS in android marshmallow 6.0? [duplicate]
Why Android is storing dynamic views in RAM?
Android RecyclerView -Multiple Edittext change simultaneously
Android Cordova SQLite Plugin not forgetting saved data whem restart App
LibGDX Tests Gradle not working: “Failed to apply plugin [id 'com.android.application'] Project contains 2 or more modules with same identification”

Categories

HOME
sonarqube
go
phantom-dsl
c99
wakanda
apache-jena
flex
toolbox
yahoo-finance
components
fftw
graphics
spring-data-redis
error-handling
vscode-extensions
r-googlesheets
zip
code-coverage
categorical-data
text-mining
plist
startup
rtf
gkturnbasedmatch
frequency-distribution
gource
modbus-tcp
null-pointer
firefox-addon
imessage
bourbon
imagemap
php-mysqlidb
scriptella
flask-sqlalchemy
windows-server-2003
quantlib
google-earth
testbed
rselenium
jett
yowsup
protege4
hivemq
gdata
jvmti
news
levenshtein-distance
photos
uiimage
servermanager
getchar
xbmc
chai-as-promised
stdmap
wpas
azure-cli
yii2-user
otp
type-theory
cpu-cache
cd-burning
donations
cronexpression
centrifuge
vulcanize
resourcemanager
beamer
pre-build-event
tracker-enabled-dbcontext
hadoop-partitioning
createprocess
gocql
iokit
avisynth
android-launcher
snoop
fits
public-html
infosphere-spl
beatsmusic
ssis-data-flow
webfinger
wcm
named-parameters
lambda-architecture
verold
ray
light
ice-cube
cmmi
epiceditor
traceability
cardreader
qtconcurrent
faye
rmiregistry
listitem
appjs
window-decoration
kqueue
cdonts
twitterizer
photolibrary
vs-android
glui
wcf-instancing
tui
windows-identity
great-circle

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App