Audio Spectrum Effect iOS/Android - java

I'm wondering if there is any way to get an audio effect like the one here
in Java and/or Objective C. It is normally done in After Effects, but I want to create it on a smartphone. I know that the x axis is frequency and the y axis is volume. Can anyone help?

I'm not sure about iOS, but if you don't mind the extra space, Eclipse can handle a .mp3 file, and you can play it using the MediaPlayer class. As for creating the file, I'm not sure .raw has enough distinct sounds.
I played an mp3 in Android using a separate Music.java class and then calling it with mp3s in res/raw/*.mp3
import android.content.Context;
import android.media.MediaPlayer;
public class Music
{
private static MediaPlayer mp = null;
//Stop old song, play new one
public static void play(Context context, int resource)
{
stop(context);
if (Prefs.isMusic(context)) //is music on?
{
mp = MediaPlayer.create(context, resource);
mp.setLooping(true);
mp.start();
}//end if
}//end play method
//Stop the music
public static void stop(Context context)
{
if(mp != null)
{
mp.stop();
mp.release();
mp = null;
}//end if
}//end stop method
}//end class Music
and the calls in my Game.java file:
Music.play(this, R.raw.game);
Music.stop(this);

Related

Android Studio Mediaplayer

I am a completely begginer guy in Android Studio and mobile apps in general. I used to create websites on Wordpress and i don't have so much experience on coding. Recently i started experimenting with mobile apps and mostly Android Studio. I bought a template for a Logo Quiz game and i managed to make it run without errors and publish it in Play Store as my first game. The player can see a part of the logo and guess the brand name using the given letters
But i would like to use the same template with new graphics and create a music quiz.
Instead of the logo guess game, the player will be able to listen a part of a song and guess the song's title.
The current project is getting the file names from a database stored in assets/databases folder.
So i managed to add start, pause and stop buttons in my activity_play.xml and succesfully created a mediaplayer in activityPlay.java file like:
public void music(View view) {
switch (view.getId()){
case R.id.button:
// Check if mediaPlayer is null. If true, we'll instantiate the MediaPlayer object
if(mediaPlayer == null){
mediaPlayer = MediaPlayer.create(this, R.raw.music);
}
// Then, register OnCompletionListener that calls a user supplied callback method onCompletion() when
// looping mode was set to false to indicate playback is completed.
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
// Here, call a method to release the MediaPlayer object and to set it to null.
stopMusic();
}
});
// Next, call start() method on mediaPlayer to start playing the music.
mediaPlayer.start();
break;
case R.id.button2:
if(mediaPlayer != null) {
// Here, call pause() method on mediaPlayer to pause the music.
mediaPlayer.pause();
}
break;
case R.id.button3:
if(mediaPlayer != null){
// Here, call stop() method on mediaPlayer to stop the music.
mediaPlayer.stop();
// Call stopMusic() method
stopMusic();
}
break;
}
}
private void stopMusic() {
mediaPlayer.release();
mediaPlayer = null;
}
// Call stopMusic() in onStop() overridden method as well.
#Override
protected void onStop() {
super.onStop();
stopMusic();
}
The above code can succesfully play the music.mp3 file located in raw folder. The app i bought is using the following code to load the images and display them for each level:
String image_a = listDataBase.get(1);
String image_q = listDataBase.get(2);
if (isTrue == 1) {
String imgPath;
if (numImage == 0) {
imgPath = "file:///android_asset/logos/" + image_a;
} else {
imgPath = "file:///android_asset/logos/" + image_q;
}
Picasso.get().load(imgPath).into(imageView);
linearLayoutNullClick.setVisibility(View.VISIBLE);
recyclerViewKeys.setVisibility(View.GONE);
trueLogo = 2;
} else {
String imgPath = "file:///android_asset/logos/" + image_q;
Picasso.get().load(imgPath).into(imageView);
recyclerViewKeys.setVisibility(View.VISIBLE);
recyclerViewLogoKeys.setVisibility(View.VISIBLE);
}
So is it possible to use the same code and load the imgPath into mediaPlayer = MediaPlayer.create(this, R.raw.music);
I tried loading imgPath directly to mediaplayer like this but didn't work:
mediaPlayer = MediaPlayer.create(this, imgPath);
Then i tried:
private String audioPath;
audioPath = imgPath;
mediaPlayer = MediaPlayer.create(this, audioPath);
but also didn't work.
Tried many more methods i found on the web, but always i am missing something
As i said before i am a newbie in coding and programming so the solution probably will be very easy .
Anyone can help please?
Are you sure you are getting a audio path in your imgPath object?
Then you can try getting actual storage path from device using code mentioned
here
If you change the value in the database of pic_1.png with audio_1.mp3
then path will start like:
"file:///android_asset/logos/" + YOUR_AUDIO;
So are you sure audio exists in this path?

Playing 2 musics through 2 different sound cards at same time

Trying something pretty out of the box... I have a simple app with a button that when pushed, plays music out of the audio jack of my android tablet.
public void btn1 (View view) {
MediaPlayer mp = MediaPlayer.create(this, R.raw.xxx);
mp.start();
}
I've now added a usb audio interface (through a micro usb adapter) and I can hear audio out of it.
I'm able to list the sound cards with this
AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
for (AudioDeviceInfo device : devices) {
int b = device.getId();
int d = device.getType();
CharSequence productName = device.getProductName();
}
How do I route music so that I can play 2 different music at once, one through usb and the other through the headphone jack?
According to the MediaPlayer documentation, you can set the audio device using setPreferredDevice which receive an AudioDeviceInfo as a parameter, see https://developer.android.com/reference/android/media/MediaPlayer.html#setPreferredDevice(android.media.AudioDeviceInfo).
You will then have to create one MediaPlayer to play on each device.
it works about like this:
protected void playAudio() {
this.playByDeviceIdx(0, R.raw.xxx);
this.playByDeviceIdx(1, R.raw.yyy);
}
protected void playByDeviceIdx(int deviceIndex, #IdRes int resId) {
/* obtain audio-output device-infos */
deviceInfos[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
/* check, if the desired index is even within bounds */
if(deviceInfos.length < deviceIndex) {
/* create an instance of MediaPlayer */
MediaPlayer mp = MediaPlayer.create(this, resId);
/* assign a preferred device to the MediaPlayer instance */
mp.setPreferredDevice(deviceInfos[deviceIndex]);
/* start the playback (only if a device exists at the index) */
mp.start();
}
}
you could also filter for the headset jack plug/unplug event:
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
Intent intent = context.registerReceiver(null, intentFilter);
boolean isConnected = intent.getIntExtra("state", 0) == 1;
sources: me, based upon the SDK documentation for the MediaPlayer.

playing sounds on simultaneous button presses

In my Launchpad Simulator there are a lot of Buttons on the main activity. I want to play sound on each button press. If the buttons are pressed simultaneously, I want to play the sound simultaneously. From what I made uptil now, it seems that Whenever I press buttons it does play the sound, but since the first sound is 3 seconds long (eg. a clap sound file is 3 seconds long in its playtime).
Before any other sound is produced through buttons, it waits 3 seconds and the plays the next sound if any button is pressed after 3 seconds and same with other 32 buttons.
Just like a launchpad as soon as I press buttons I want a sound to be played. In this case the clap sound.
Here is the Java Code:
MainActivity.java
package com.oniichansblog.launchpadify;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.media.MediaPlayer;
public class MainActivity extends AppCompatActivity {
private MediaPlayer clap1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
clap1 = MediaPlayer.create(this, R.raw.clap1);
}
public void clap1(View v){
clap1.start();
}
}
I only have this one function clap1() that is being called over and over everytime I press a button.
if you want to check it for yourself I have a repository:
GitHub Repository for LaunchPadify
I'd recommend to not define the MediaPlayer above.
Just create a new temporary MediaPlayer every ButtonClick
new MediaPlayer.create(this, R.raw.clap).start();
and it will play sounds simultaneously
UPDATE
If you want to destroy a MediaPlayer after it finishes playing the sound, you can do this by using this code
new MediaPlayer.create(getApplicationContext(), R.raw.test)
.start()
.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
To play several tracks simultaneously you should use AsyncTask and execute it on THREAD_POOL_EXECUTOR.
How to do this:
Thread class:
class PlayThread extends AsyncTask<MediaPlayer, Void, Void>
{
#Override
protected Void doInBackground(MediaPlayer... player) {
player[0].start();
return null;
}
}
Media Players:
MediaPlayer[] players = new MediaPlayer[5];
//Then set source to each player...
//...
//Create objects of Thread class
PlayThread[] playThreads = new PlayThread[5];
for (int i = 0; i < 5; i++)
playThreads[i] = new PlayThread();
//Set Media Players there and start play
for (int i = 0; i < 5; i++)
playThreads[i].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, players[i]);
AsyncTask can execute only 5 Threads simultaneously, other are going to queue.
SoundPool buffer limit is 1Mb, so it is not a solution at all.
It is very important:
To play simultaneously more audio tracks you should mix them into 1 buffer.
The way to do this: decode mp3 to pcm (to small buffers in stream mode), mix it into one byte buffer and put it to AudioTrack for playing.

Check and see if a sound is playing, wait for it to finish and then play another

What i am trying to acomplish is for me to click on a button and then play a sound based on a substring.
This is my current code for pressing the button :
display.setText("start");
thefull = thef.getText().toString();
for(int a=0;a<thefull.length();a++)
{
letter=thefull.substring(a,a+1);
if(letter=="m")
{
oursong = MediaPlayer.create(MainActivity.this, R.raw.m);
oursong.start();
while(oursong.isPlaying())
{
display.setText("start");
}
oursong.release();
}
else if(letter=="a")
{
oursong = MediaPlayer.create(MainActivity.this, R.raw.a);
oursong.start();
while(oursong.isPlaying())
{
display.setText("start");
}
oursong.release();
}
display.setText("done");
but for some reason when i click my button no sound is played.
I am also new to android and java programming, so am i going right about doing this?
Because what i really want is for the program to keep checking if a sound is playing(in this case "oursound) when the button is clicked and if the sound is playing i want the program to wait for it to finish to start another sound right after it.
But for now my code doesn´t play any sounds
First of all you need to stop the media player before releasing it(its safer.)
Second, instead of using while(oursong.isPlaying())
{
display.setText("start");
} ; you have to register OnCompletionListener using setOnCompletionListener method. When the song is played endCompletion will be called. Like so;
MediaPlayer mp = new MediaPlayer();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer player) {
player.release();
}});
and inside the onComplete should reset the text "done"

How do I play an audio file in Android?

I have code to play an .ogg audio file, that I downloaded from the internet. I have no errors, so I can run it, but then the app crashes:
package play.my.sound;
import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
public class PlaySound2Activity extends Activity {
private SoundPool soundPool;
private int soundID;
boolean loaded = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View view = findViewById(R.id.textView1);
view.setOnClickListener((OnClickListener) this);
// Set the hardware buttons to control the music
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
soundID = soundPool.load("sound1.ogg", 1);
}
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Getting the user sound settings
AudioManager audioManager = (AudioManager) getSystemService (AUDIO_SERVICE);
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
// Is the sound loaded already?
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
Log.e("Test", "Played sound");
}
}
return false;
}
}
I think I have two problems:
I put this in the main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:text="Click on the screen to start playing"
android:id="#+id/textView1" android:layout_width="fill_parent"
android:layout_height="fill_parent"></TextView>
</LinearLayout>
And I don't know if it's correct.
I put the file sound1.ogg in the workspace->SoundPlay2 folder because in the res folder I had problems, and also, I tried to put it in the two res folders that exist.
This is from my console:
[2012-01-04 19:38:16 - PlaySound2] Failed to install PlaySound2.apk on device 'emulator-5554': timeout
[2012-01-04 19:38:16 - PlaySound2] Launch canceled!
[2012-01-04 19:47:33 - PlaySound2] Error in an XML file: aborting build.
[2012-01-04 19:52:34 - PlaySound2] res\layout\main.xml:0: error: Resource entry main is already defined.
[2012-01-04 19:52:34 - PlaySound2] res\layout\main.out.xml:0: Originally defined here.
[2012-01-04 19:52:34 - PlaySound2] C:\Users\Natalia\workspace\PlaySound2\res\layout\main.out.xml:1: error: Error parsing XML: no element found
I took this example from "Android Sounds - Tutorial".
I want to play an audio file, more specifically, a .wav file.
I dont' know where I can find some information about the files that are permitted in the MediaPlayer class and their characteristic (durantion, sample rate...) Could you tell me where I can find this??
Create raw folder in the res folder and add your file to it. Then play the file using
soundID = soundPool.load(R.raw.sound1, 1);
And also see this post for your main.xml problem.
I've never seen the Class SoundPool before, however I would recommend using a MediaPlayer Class:
mMediaPlayer = new MediaPlayer(this, R.raw.yourfile);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.prepare();
mMediaPlayer.start();
Make sure you put the file into the folder PROJECT/res/raw/ (or create it if it does not exist)
Also there is something wrong with your main.xml. Can you please post it?
Example for playing some kind of buzzer. In the res folder under raw folder I have a buzzer.wav
Method to play this buzzer:
/**
* Method to play an alarm sound to signal half time or full time.
*/
private void playAlarm() {
MediaPlayer mp = MediaPlayer.create(this,
R.raw.buzzer);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
first you need to save sound1.ogg file in src\main\res\raw directory
instated of direct passing "sound1.ogg" file , pass file this way R.raw.sound1
soundID = soundPool.load(R.raw.sound1, 1);
To be honest I would always prefer Mediaplayer over any other api.After downloading file save it to external storage or raw folder and play it using the given methods or you can directly play it from internet.Caution: Be careful of buffering.
To play audio directly from internet add these code. Note: Api version >= 21 and make sure to add internet permission in manifest
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)//This method requires android version more than 20
public void playSoundFrom_internet(String url) {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();
}catch(IOException E){
E.printStackTrace();
}
}
To play audio from res folder:
public void playSoundFrom_raw(#RawRes int rawId, Context context){
MediaPlayer mediaPlayer = MediaPlayer.create(context,rawId);
mediaPlayer.start();
}
To play audio from file. Note: Make sure to add storage permission
public void playSoundFrom_file(String filePath){
try {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
That's not how OnClickListener be implemented, that's an Interface to implement in the class not force casted to. You did that as a quick fix but blew back onto you since AudioManager got running first so you thought that is at fault.

Categories