Recording and playing audio. Approaches For playing audio – Play a stream with media player Easiest Works with compressed files Works with urls and files.

Slides:



Advertisements
Similar presentations
Android Application Development Tutorial. Topics Lecture 4 Overview Overview of Sensors Programming Tutorial 1: Tracking location with GPS and Google.
Advertisements

SQLite. Command line sqlite3 The command line sqlite3 is not installed on all devices To install, get sqlite3 from web page, and $ adb push sqlite3 /sdcard/
Java File I/O. File I/O is important! Being able to write and read from files is necessary and is also one common practice of a programmer. Examples include.
Cosc 5/4730 Multimedia Part 1: Audio media. PLAYING AUDIO Android android.media.
Advanced Audio Setup Troubleshooting your audio Users’ Reference.
Group 8: Dylan Lentini (AE), Mandy Minuti (WSE), Jean Paul Galea (TL)
COMPUTER PROGRAMMING 2 Chapter 7 Sound. Objectives Find out how to prepare sounds for inclusion in Microsoft XNA projects. Incorporate sounds into XNA.
Chapter 6 Jam! Implementing Audio in Android Apps.
Chapter 6: Jam! Implementing Audio in Android Apps.
The Online Guide to Creating Podcasts Presented by The Portland Public Schools Multimedia Library Recording and Saving your Podcast.
Recording and playing audio. App Make app AudioFun with 4 buttons – Start recording (id=StartRecording) – Stop recording (id=StopRecording) – Start playback.
Cosc 5/4730 Game Design. A short game design primer. A game or animation is built on an animation loop. – Instance variables of “objects” are updated.
1 CS 177 Week 15 Recitation Slides Review. Announcements Final Exam on Sat. May 8th  PHY 112 from 8-10 AM Complete your online review of your classes.
Debugging Android Applications
Video upload and streaming
CS371m - Mobile Computing Audio.
Getting Started with Android Programming Note: if you have already installed android development tools, please check that you have the same version as.
Games and Simulations O-O Programming in Java The Walker School
Basic Audio and Video. Audio Primary components – Audio file stored in ‘raw’ folder within ‘res’ folder ‘raw’ directory must be created while many formats.
Multimedia.
Creating Mobile Apps with App Inventor! Day 5 Google search Kris Gordon Ludlow for links.
ELecta Live Update What’s new in Version 4.8 What’s New in V. 4.8 February
CS5103 Software Engineering Lecture 08 Android Development II.
CSE 486/586, Spring 2013 CSE 486/586 Distributed Systems Content Providers & Services.
Programming with Alice Computing Institute for K-12 Teachers Summer 2011 Workshop.
Audio and Video CGS Some Common Audio Formats Format Use Extension MIDI instrumental music.mid MPEG songs.mp3 RealAudio live broadcasts.ra Wave.
Data Storage: Part 2 (File System). Internal Storage versus External Storage Internal storage − for private data –By default, files saved to the internal.
Threads some important concepts Simon Lynch
CSE 486/586, Spring 2012 CSE 486/586 Distributed Systems Recitation.
Chapter 2 The Android User Interface. Objectives  In this chapter, you learn to:  Develop a user interface using the TextView, ImageView, and Button.
Copyright © Curt Hill Sounds, Resource Packs, JSON What more would you want?
Threads and Services. Background Processes One of the key differences between Android and iPhone is the ability to run things in the background on Android.
Chapter 9 1 Chapter 9 – Part 1 l Overview of Streams and File I/O l Text File I/O l Binary File I/O l File Objects and File Names Streams and File I/O.
Change sound track. What to Learn Able to split the sound track from a video by – Right click a clip – Split audio button Know the difference of voice.
HOW TO USE for Audio Diaries click for teacher instructions click for student instructions for smartphone instructions.
Tracking Tasks and Processes. GET_TASK Make a new app, WatchProcesses – Add permission GET_TASK This permission allows the app to collect lots of information.
Li Tak Sing COMPS311F. Case study: consumers and producers A fixed size buffer which can hold at most certain integers. A number of producers which generate.
Services A Service is an application component that can perform long-running operations in the background and does not provide a user interface. An application.
Camera. Make new project – CameraFun – Give permission to use camera write_external _storage Make two buttons – id takePictureButton – id showLastPicButton.
User Interface Android Club Agenda Button OnClickListener OnLongClickListener ToggleButton Checkbox RatingBar AutoCompleteTextView.
CS378 - Mobile Computing Persistence. Saving State We have already seen saving app state into a Bundle on orientation changes or when an app is killed.
Li Tak Sing COMPS311F. Threads A thread is a single sequential flow of control within a program. Many programming languages only allow you to write programs.
HTML 5. Introduction In modern browsers, adding a video to your page is as easy as adding an image. No longer do you need to deal with special plug-ins.
Fall 2002CS 150: Intro. to Computing1 Streams and File I/O (That is, Input/Output) OR How you read data from files and write data to files.
Edgewood Ward 7 JUN 2015 Dan Eliason, Assistant Ward Clerk AUDIO FILES on SEARCH FAMILY.
Digital Storytelling Use of Windows Live Movie Maker to create a digital story using the “Auto” function. Create a digital story in minutes! Sept 2010Malcolm.
1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit.
CS378 - Mobile Computing Audio.
Multimedia. Audio,vedio and Images End user typically refer to vedio/audio using the respective file format MP4 or AVI(audio vedio interleave) Developer.
L6: Threads “the future is parallel” COMP206, Geoff Holmes and Bernhard Pfahringer.
Field Trip #30 A Memory Game By Keith Lynn. View A View is the basic building block of an app Some Views hold other views An example of this is GridLayout.
Using Audacity Let’s get Started Open Audacity. Getting started…
Lecture 7: Media Player Topics: Media Player, Async prepare Date: Mar 3, 2016.
Creating a Podcast using GarageBand Symphonic Band Project: An Introduction to Musical Instruments.
By: Eliav Menachi.  On Android, all application data (including files) are private to that application  Android provides a standard way for an application.
CS371m - Mobile Computing Audio. Audio on Device Devices have multiple audio streams: – music, alarms, notifications, incoming call ringer, in call volume,
Audio and Haptic Feedback
Android Application Audio 1.
Multimedia.
Lecture 7: Service Topics: Services, Playing Media.
Android Boot Camp for Developers Using Java, 3E
Change sound track.
Lecture 25 More Synchronized Data and Producer/Consumer Relationship
Lecture 7: Media Player Topics: Media Player, Async prepare
CS5103 Software Engineering
ConnectPro User Guide for Students
File I/O in C Lecture 7 Narrator: Lecture 7: File I/O in C.
We’re moving on to more recap from other programming languages
Android Topics UI Thread and Limited processing resources
Lecture 7: Service Topics: Services, Broadcast Receiver, Playing Media.
Presentation transcript:

Recording and playing audio

Approaches For playing audio – Play a stream with media player Easiest Works with compressed files Works with urls and files Works with shoutcast streams – Use audio tracks With pcm only – Allows you to make sounds on the fly – Might be too slow to decompress on the fly (use media player for compressed audio) Low latency for short files that fit in memory Higher latency for longer files – But will need to repeatedly fill buffer (this is why media play is easier) – JET For playing MIDI audio Good for making a keyboard app – Short delay from button to sound Not covered this semester – Sound pool Store a bunch of optionally compressed files (included in app) Predecompress Play quickly on demand Good for game sound effects Not covered For recording – Media player Can record and compressed Easy – AudioRecord Record pcm Need to empty buffer NDK – Open SL ES – Can decompress to pcm Allows sound effects (equalization, reverb, etc.) to be added – Maybe we will cover this later in the semester

MediaPlayer Make app MediaPlayerFun with 4 buttons – Start recording (id=StartRecordingButton) – Stop recording (id=StopRecordingButton) – Start playback (id=StartPlaybackButton) – Stop playback (id=StopPlaybackButton) Include permission to – Record Audio – Use Internet – There is no permission to play on audio device. So a malicious app could play a scary noise in the middle of the night! Include three class attributes for this activity – final private static String FILE_NAME = "audio.mp4"; – MediaRecorder audioRecorder; – MediaPlayer audioPlayer; – String pathForAppDataFiles;

Recording (1) Make onClickListener for startRecordingButton – startRecordingButton.setOnClickListener(new View.OnClickListener() {} ); Get MediaRecorder – if (audioRecorder!=null) audioRecorder.release(); – if (audioRecorder == null) audioRecorder = new MediaRecorder(); Get path for file – Note: each app runs in its own VM, with its own private directory and files. The SDK provides several tools for accessing the apps directory and files – The apps directory is at /data/data/ – Files are at /data/data/ /files FileOutputStream fos; // in java.io.FileOutputStream fos = Context.openFileOutput(“filename.txt”,MODE_PRIVATE); // opens file /data/data/ /files/filename.txt for writing – similarly FileInputStream fis; // in java.io.FileOutputStream fis = Context.openFileInput(“filename.txt”); // opens file /data/data/ /files/filename.txt for reading MediaRecorder and MediaPlayer need the full path In OnCreate, add – pathAndNameOfAudioFile = getFilesDir().getAbsolutePath(); // returns /data/data/ /files – pathAndNameOfAudioFile += "/"+FILE_NAME; // file name with full path

logging The SDK provides logging – Log.e(tag, string) – E.g., add class attribute – String TAG = "MediaPlayerFun"; – Log.e(TAG,"Set file name: "+pathAndNameOfAudioFile); – The log can be seen from the DDMS – Or from the command line C:\android\android-sdk-windows\platform-tools> adb –d logcat C:\android\android-sdk-windows\platform-tools> adb –e logcat

Set up media recorder audioRecorder.setAudioSource(MediaRecorder.Au dioSource.MIC); – Options instead of MIC : CAMCORDER Microphone audio source with same orientation as camera if available, the main device microphone otherwise DEFAULT MIC Microphone audio source VOICE_CALL Voice call uplink + downlink audio source // remember this when we record phone calls VOICE_DOWNLINK Voice call downlink (Rx) audio source VOICE_RECOGNITION Microphone audio source tuned for voice recognition if available, behaves like DEFAULT otherwise. VOICE_UPLINK Voice call uplink (Tx) audio source audioRecorder.setOutputFormat(MediaRecorder. OutputFormat.DEFAULT); – options DEFAULT MPEG_4: MPEG4 media file format THREE_GPP :3GPP media file format AMR (adaptive multi-rate) good for speech RAW_AMR AMR_NB NB = narrowband – Silence detection AMR_WB – Wv = wideband – Same as G FLAC and.ogg are missing? Maybe added later audioRecorder.setAudioEncoder(MediaRe corder.AudioEncoder.DEFAULT); – options ACC AMR_NB : AMR (Narrowband) for speech AMR_WB: (AMR (wideband) DEFAULT audioRecorder.setOutputFile(pathAndNa meOfAudioFile);

Record try { audioRecorder.prepare(); audioRecorder.start(); } catch (Exception e) { Log.e(TAG, "Failed to prepare and start audio recording", e); } startRecordingButton.setVisibility(View.INVISIBLE); //stopRecordingButton.setVisibility(View.VISIBLE); //startPlaybackButton.setVisibility(View.INVISIBLE); //stopPlaybackButton.setVisibility(View.INVISIBLE);

Stop recording Make onClickListener for stopRecordingButton if (audioRecorder==null) return; audioRecorder.stop(); audioRecorder.release(); audioRecorder = null; Log.e(TAG,"Finished recording"); Make nice buttons startRecordingButton.setVisibility(View.VISIBLE); stopRecordingButton.setVisibility(View.INVISIBLE); //startPlaybackButton.setVisibility(View.INVISIBLE); //stopPlaybackButton.setVisibility(View.INVISIBLE); Try it Run on device or emulator emulator is slow, so the quality is bad Get file from emulator using the DDMS and play in quickTime Get file from device via adb adb -d pull /data/data/edu.udel.eleg454.AudioFun/files/audio.mp4 c:\audio.mp4

Playback Make startPlaybackButton and onClickListener Button startPlaybackButton = (Button)findViewById(R.id.startPlaybackButton); startPlaybackButton.setOnClickListener(new View.OnClickListener() {}); Add to listener – //Get clean MediaPlayer if (audioPlayer!=null) – audioPlayer.release(); if (audioPlayer == null) – audioPlayer = new MediaPlayer (); – //Play try { – audioPlayer.setDataSource(pathAndNameOfAudioFile); – audioPlayer.prepare(); – audioPlayer.start(); } catch (Exception e) { – Log.e(TAG, "Playback failed.", e); } Try it… it fails The file cannot be opened for reading

File Permissions Problem: the file does not have the correct permissions. See adb shell … ls –l There are several ways to fix this. Use the file descriptor from when the file was created. But what if we want to play a file that was not created when we run the app this time Change permissions with chmod – easiest option – Android might not support exec() in the future! – Sloppy – String command = "chmod 666 " + pathAndNameOfAudioFile.toString(); – try { – Runtime.getRuntime().exec(command); – } catch (IOException e1) { – Log.e("SetPermissions", "Couldn't set permissions", e1); – } Better approach. – Just after the filename is set, add FileOutputStream fos; try { – fos = openFileOutput(FILE_NAME, Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE); – fos.close(); } catch (FileNotFoundException e1) { – Log.e(TAG,"could not open file"); – return; } catch (IOException e) { – Log.e(TAG,"could not close the file"); – return; }

When finished playing It is important to release the mediaPlayer resource when you are done playing Inside startPlaybackButton.setOnClickListener(new View.OnClickListener() {, add – audioPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){ public void onCompletion(MediaPlayer mp) { – startRecordingButton.setVisibility(View.VISIBLE); – stopRecordingButton.setVisibility(View.INVISIBLE); – startPlaybackButton.setVisibility(View.VISIBLE); – //stopPlaybackButton.setVisibility(View.INVISIBLE); – audioPlayer.release(); – audioPlayer = null; }} );

Stopping playback final Button stopPlaybackButton = (Button)findViewById(R.id.stopPlaybackButton); stopPlaybackButton.setOnClickListener(new View.OnClickListener() {}); In onClick, add – startRecordingButton.setVisibility(View.VISIBLE); – stopRecordingButton.setVisibility(View.INVISIBLE); – startPlaybackButton.setVisibility(View.VISIBLE); – stopPlaybackButton.setVisibility(View.INVISIBLE); – if (audioPlayer==null) return; – audioPlayer.stop(); – audioPlayer.release(); – audioPlayer = null;

Volume Control AudioManager Add toggleButton to UI – Id = toggleVolume In MediaPlayerFunActivity, – Add member variable AudioManager audioManager = null; – In onCreate, add audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); Make onClickListener for ToggleButton – In onCreate, add ToggleButton toggleVolumeButton = (ToggleButton)findViewById(R.id.toggleVolume); toggleVolumeButton.setOnClickListener(new View.OnClickListener(){}); – In onClick, add if (((ToggleButton) v).isChecked()) { – audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), AudioManager.FLAG_SHOW_UI); } else { – audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, AudioManager.FLAG_SHOW_UI); } AudioManager can be used to – set the volume of the ringer, in call, vibrate – Determine if music is playing – get the volume – Determine if the speakerphone is on – Play sound effect (clicks etc)

Play music from a stream In startPlaybackButton onClickListener, replace – audioPlayer.setDataSource(pathAndNameOfAudio File); With – Uri uri = Uri.parse(" – audioPlayer.setDataSource(MPFActivity.this, uri); Note that this url as found insider a.pls file, which can be found online. Browsers can decode pls files. But the AudioPlayer cannot.

Missing Topics Audio Focus – What to do when there are multiple audio streams? – One should play and the other should be silent – The app that has audio focus should play – You check request audio focus before playing. And only play if you get it Remote control – When the screen is locked, you might want to adjust the volume. Remote controls allow you to do this Wake Lock – If you are streaming, the system should stay awake even when the screen is off. – Wake locks do this – We cover wake locks later

AudioRecord and AudioTrack AudioTrack plays audio from a buffer The audio must be decompressed Make a new app, AudioTrackFun – Make some sounds and play them two buttons – Go – stop Member variables – AudioTrack audioTrack = null; – int sampleRate = 8000;//22050; – int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; – int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // must be this – static short[] audioData; // buffer for data – int bufferSize;

Set up AudioTrack AudioTrack needs a buffer. When constructing an AudioTrack object, we must say how big this buffer should be. – Sometimes it makes sense to have a small buffer – In onCreate, add bufferSize = 10*AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat); Make audioTrack object – In onCreate add audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfig, audioFormat, 2*bufferSize, AudioTrack.MODE_STREAM); – note that the buffer size is in shorts (2 bytes) so we multiple by 2 Make buffer – In onCreate add audioData = new short[bufferSize]; Must release audio resources – public void onDestroy() { super.onDestroy(); if (audioTrack!=null) – audioTrack.release();

Button to start and stop Button startButton = (Button)findViewById(R.id.startButton); startButton.setOnClickListener(new View.OnClickListener() {}); In onClick, add – startAudio(); Button stopButton = (Button)findViewById(R.id.stopButton); stopButton.setOnClickListener(new View.OnClickListener() {}); In onClick, add – stopAudio();

Fill audio buffer We can fill the buffer with decompressed music, received audio (e.g., VoIP), or synthesized sound Make member function and variables – float t = 0, dt = (float)(1.0/(float)sampleRate); – float pi = (float) ; – float w1=(float) 300*2*pi, w2=(float) 10*2*pi, a=(float)(100.0*2.0*pi); – public void fillAudioData(int length) { for (int i=0; i<length; i++) { – audioData[i] = (short) (Short.MAX_VALUE*Math.cos((w1+a*Math.cos(w2*t))*t)); // fm synthesizer like the yamaha DX-7 – t += dt; – if (t>10) » t = 0; } – }

Playing audio (approach 1) void startAudio() { – fillAudioData(bufferSize); – audioTrack.write(audioData, 0, bufferSize); – fillAudioData(bufferSize/2); // get data ready – audioTrack.setNotificationMarkerPosition(bufferSize/2); // setPositionNotificationPeriod is another possibility – audioTrack.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener() {}); – In onMarkerReached, add track.write(audioData, 0, bufferSize/2); audioTrack.setNotificationMarkerPosition(bufferSize/2); // must reset everytime fillAudioData(bufferSize/2); // get next data ready – audioTrack.play(); – }

stop public void stopAudio() { – audioTrack.stop(); } Try it Note that the UI is delayed because we are working in the UI thread

Use thread instead of notification Drawbacks of notification – It is not possible to check how full the buffer is. – try to write a larger buffer and wait – For sure this will block and delay the UI thread One can use notifications and threads. But a direct thread approach seems to work well – boolean stop = false; // new member variable – public void startAudio() { fillAudioData(bufferSize); audioTrack.write(audioData, 0, bufferSize); fillAudioData(bufferSize/2); // get data ready Thread thread = new Thread(new Runnable() { – public void run() { » stop = false; » while (!stop) { audioTrack.write(audioData, 0, bufferSize/2); fillAudioData(bufferSize/2); » } » Log.e("AudioFun","Thread has stopped"); – }}); thread.start(); audioTrack.play(); – }

stopAudio Update to public void stopAudio() { – audioTrack.stop(); – stop = true; }

AudioRecord We will record from mic and then play it right back to speaker – In your project, you could send the recording to another host. – Use MediaPlayer to record to a file Add member variable – AudioRecord audioRecord = null; – int amountOfDataReady; In onCreate, just after bufferSize = …, add – bufferSize = Math.max(bufferSize,10*AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat)); – audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channelConfig, audioFormat, 2*bufferSize ); New version of startAudio – public void startAudio() { – Thread thread = new Thread(new Runnable() public void run() { – stop = false; – while (!stop) { » amountOfDataReady = audioRecord.read(audioData, 0, bufferSize/2); » audioTrack.write(audioData, 0,amountOfDataReady); – } – Log.e("AudioFun","Thread has stopped"); }}); thread.start(); audioTrack.play(); audioRecord.startRecording(); – }

Buffer size Try it. As expected, there is feedback loop. The delay is quite large. This would not work so well for VoIP How small can we make the buffer? It depends on how much other things are going on More member variables – long currentTime, lastTime; – boolean starting = true; – int bufferToUse;

d = max(a*d, sampledDelay); Buffer = 1.5d/sampleRate