diff options
| author | Marco Nelissen <marcone@google.com> | 2011-06-23 14:05:10 -0700 |
|---|---|---|
| committer | Marco Nelissen <marcone@google.com> | 2011-06-24 13:32:44 -0700 |
| commit | 66f2cfede1affd65ebc0b2e6854d2aabcfd9bb90 (patch) | |
| tree | 8ca7b14e2caa0b2d5532cf529952b7b4ea150e2c /src/com | |
| parent | f2f3fcd148769c5189c0d41c6ca85a8f14e6b534 (diff) | |
| download | platform_packages_apps_MusicFX-66f2cfede1affd65ebc0b2e6854d2aabcfd9bb90.tar.gz platform_packages_apps_MusicFX-66f2cfede1affd65ebc0b2e6854d2aabcfd9bb90.tar.bz2 platform_packages_apps_MusicFX-66f2cfede1affd65ebc0b2e6854d2aabcfd9bb90.zip | |
Remove DOS line endings.
Diffstat (limited to 'src/com')
| -rw-r--r-- | src/com/android/audiofx/OpenSLESConstants.java | 248 | ||||
| -rw-r--r-- | src/com/android/musicfx/ActivityBrowser.java | 240 | ||||
| -rw-r--r-- | src/com/android/musicfx/ActivityFirstUse.java | 192 | ||||
| -rw-r--r-- | src/com/android/musicfx/ActivityLauncher.java | 186 | ||||
| -rw-r--r-- | src/com/android/musicfx/ActivityMusic.java | 2050 | ||||
| -rw-r--r-- | src/com/android/musicfx/Common.java | 208 | ||||
| -rw-r--r-- | src/com/android/musicfx/ControlPanelEffect.java | 2848 | ||||
| -rw-r--r-- | src/com/android/musicfx/ControlPanelReceiver.java | 210 | ||||
| -rw-r--r-- | src/com/android/musicfx/FirstUseReceiver.java | 94 |
9 files changed, 3138 insertions, 3138 deletions
diff --git a/src/com/android/audiofx/OpenSLESConstants.java b/src/com/android/audiofx/OpenSLESConstants.java index 7c92655..1109ce5 100644 --- a/src/com/android/audiofx/OpenSLESConstants.java +++ b/src/com/android/audiofx/OpenSLESConstants.java @@ -1,124 +1,124 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.audiofx;
-
-/**
- * OpenSL ES constants class
- */
-public final class OpenSLESConstants {
- private OpenSLESConstants() {
- // Empty constructor
- }
-
- /**
- * Minimum volume level in millibel (mb).
- */
- public static final short SL_MILLIBEL_MIN = -9600;
- /**
- * This value is used when equalizer setting is not defined.
- */
- public static final short SL_EQUALIZER_UNDEFINED = (short) 0xFFFF;
-
- /**
- * The minimum bass boost strength in o/oo.
- */
- public static final short BASSBOOST_MIN_STRENGTH = 0;
- /**
- * The maximum bass boost strength in o/oo.
- */
- public static final short BASSBOOST_MAX_STRENGTH = 1000;
-
- /**
- * The minimum reverb room level in mb.
- */
- public static final short REVERB_MIN_ROOM_LEVEL = SL_MILLIBEL_MIN;
- /**
- * The maximum reverb room level in mb.
- */
- public static final short REVERB_MAX_ROOM_LEVEL = 0;
- /**
- * The minimum reverb room HF level in mb.
- */
- public static final short REVERB_MIN_ROOM_HF_LEVEL = SL_MILLIBEL_MIN;
- /**
- * The maximum reverb room HF level in mb.
- */
- public static final short REVERB_MAX_ROOM_HF_LEVEL = 0;
- /**
- * The minimum reverb decay time in ms.
- */
- public static final short REVERB_MIN_DECAY_TIME = 100;
- /**
- * The maximum reverb decay time in ms.
- */
- // XXX: OpenSL ES is normally 20000 but can only support 7000 for now
- public static final short REVERB_MAX_DECAY_TIME = 7000;
- /**
- * The minimum reverb decay HF ratio in o/oo.
- */
- public static final short REVERB_MIN_DECAY_HF_RATIO = 100;
- /**
- * The maximum reverb decay HF ratio in o/oo.
- */
- public static final short REVERB_MAX_DECAY_HF_RATIO = 2000;
- /**
- * The minimum reverb level in mb.
- */
- public static final short REVERB_MIN_REVERB_LEVEL = SL_MILLIBEL_MIN;
- /**
- * The maximum reverb level in mb.
- */
- public static final short REVERB_MAX_REVERB_LEVEL = 2000;
- /**
- * The minimum reverb diffusion in o/oo.
- */
- public static final short REVERB_MIN_DIFFUSION = 0;
- /**
- * The maximum reverb diffusion in o/oo.
- */
- public static final short REVERB_MAX_DIFFUSION = 1000;
- /**
- * The minimum reverb density in o/oo.
- */
- public static final short REVERB_MIN_DENSITY = 0;
- /**
- * The maximum reverb density in o/oo.
- */
- public static final short REVERB_MAX_DENSITY = 1000;
-
- /**
- * The minimum virtualizer strength in o/oo.
- */
- public static final short VIRTUALIZER_MIN_STRENGTH = 0;
- /**
- * The maximum virtualizer strength in o/oo.
- */
- public static final short VIRTUALIZER_MAX_STRENGTH = 1000;
-
- /**
- * The minimum volume effect level in millibel (mb).
- */
- public static final short VOLUME_MIN_LEVEL = SL_MILLIBEL_MIN;
- /**
- * The minimum volume stereo position in o/oo.
- */
- public static final short VOLUME_MIN_STEREO_POSITION = -1000;
- /**
- * The maximum volume stereo position in o/oo.
- */
- public static final short VOLUME_MAX_STEREO_POSITION = 1000;
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.audiofx; + +/** + * OpenSL ES constants class + */ +public final class OpenSLESConstants { + private OpenSLESConstants() { + // Empty constructor + } + + /** + * Minimum volume level in millibel (mb). + */ + public static final short SL_MILLIBEL_MIN = -9600; + /** + * This value is used when equalizer setting is not defined. + */ + public static final short SL_EQUALIZER_UNDEFINED = (short) 0xFFFF; + + /** + * The minimum bass boost strength in o/oo. + */ + public static final short BASSBOOST_MIN_STRENGTH = 0; + /** + * The maximum bass boost strength in o/oo. + */ + public static final short BASSBOOST_MAX_STRENGTH = 1000; + + /** + * The minimum reverb room level in mb. + */ + public static final short REVERB_MIN_ROOM_LEVEL = SL_MILLIBEL_MIN; + /** + * The maximum reverb room level in mb. + */ + public static final short REVERB_MAX_ROOM_LEVEL = 0; + /** + * The minimum reverb room HF level in mb. + */ + public static final short REVERB_MIN_ROOM_HF_LEVEL = SL_MILLIBEL_MIN; + /** + * The maximum reverb room HF level in mb. + */ + public static final short REVERB_MAX_ROOM_HF_LEVEL = 0; + /** + * The minimum reverb decay time in ms. + */ + public static final short REVERB_MIN_DECAY_TIME = 100; + /** + * The maximum reverb decay time in ms. + */ + // XXX: OpenSL ES is normally 20000 but can only support 7000 for now + public static final short REVERB_MAX_DECAY_TIME = 7000; + /** + * The minimum reverb decay HF ratio in o/oo. + */ + public static final short REVERB_MIN_DECAY_HF_RATIO = 100; + /** + * The maximum reverb decay HF ratio in o/oo. + */ + public static final short REVERB_MAX_DECAY_HF_RATIO = 2000; + /** + * The minimum reverb level in mb. + */ + public static final short REVERB_MIN_REVERB_LEVEL = SL_MILLIBEL_MIN; + /** + * The maximum reverb level in mb. + */ + public static final short REVERB_MAX_REVERB_LEVEL = 2000; + /** + * The minimum reverb diffusion in o/oo. + */ + public static final short REVERB_MIN_DIFFUSION = 0; + /** + * The maximum reverb diffusion in o/oo. + */ + public static final short REVERB_MAX_DIFFUSION = 1000; + /** + * The minimum reverb density in o/oo. + */ + public static final short REVERB_MIN_DENSITY = 0; + /** + * The maximum reverb density in o/oo. + */ + public static final short REVERB_MAX_DENSITY = 1000; + + /** + * The minimum virtualizer strength in o/oo. + */ + public static final short VIRTUALIZER_MIN_STRENGTH = 0; + /** + * The maximum virtualizer strength in o/oo. + */ + public static final short VIRTUALIZER_MAX_STRENGTH = 1000; + + /** + * The minimum volume effect level in millibel (mb). + */ + public static final short VOLUME_MIN_LEVEL = SL_MILLIBEL_MIN; + /** + * The minimum volume stereo position in o/oo. + */ + public static final short VOLUME_MIN_STEREO_POSITION = -1000; + /** + * The maximum volume stereo position in o/oo. + */ + public static final short VOLUME_MAX_STEREO_POSITION = 1000; +} diff --git a/src/com/android/musicfx/ActivityBrowser.java b/src/com/android/musicfx/ActivityBrowser.java index ccdc0d7..2ab006f 100644 --- a/src/com/android/musicfx/ActivityBrowser.java +++ b/src/com/android/musicfx/ActivityBrowser.java @@ -1,120 +1,120 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.musicfx;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.Color;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.webkit.WebView;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-public class ActivityBrowser extends Activity {
-
- private final static String TAG = "MusicFXActivityBrowser";
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- final Intent intent = getIntent();
- final String urlString = intent.getDataString();
- try {
- final WebView webView = new WebView(this);
- final URL url = new URL(urlString);
- new LoadURLTask(webView).execute(url);
- } catch (final MalformedURLException e) {
- Log.e(TAG, "MalformedURLException " + urlString);
- }
- }
-
- /**
- * ASync Task that checks if the site is reachable and then loads the URL.
- */
- private class LoadURLTask extends AsyncTask<URL, Void, Boolean> {
- final WebView mWebView;
- String mURLString;
-
- public LoadURLTask(final WebView webView) {
- mWebView = webView;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.os.AsyncTask#doInBackground(Params[])
- */
- @Override
- protected Boolean doInBackground(final URL... urls) {
-
- final URL url = urls[0];
- mURLString = url.toString();
-
- boolean isSiteReachable = false;
- final HttpURLConnection httpURLConnection;
- try {
- httpURLConnection = (HttpURLConnection) url.openConnection();
- final int response = httpURLConnection.getResponseCode();
- if (response == HttpURLConnection.HTTP_OK) {
- isSiteReachable = true;
- }
- } catch (final IOException e) {
- Log.e(TAG, "Error connecting to " + mURLString);
- }
- return isSiteReachable;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
- */
- @Override
- protected void onPostExecute(final Boolean isReachable) {
- if (isReachable) {
- mWebView.setBackgroundColor(Color.BLACK);
- setContentView(mWebView);
- mWebView.loadUrl(mURLString);
- } else {
- createAndShowNetworkDialog();
- }
- }
- }
-
- /**
- * Shows the network dialog alerting the user that the net is down.
- */
- private void createAndShowNetworkDialog() {
- new AlertDialog.Builder(this).setTitle(R.string.browser_error_dialog_title)
- .setMessage(R.string.browser_error_dialog_text)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int which) {
- finish();
- }
- }).show();
- }
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.musicfx; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.os.AsyncTask; +import android.os.Bundle; +import android.util.Log; +import android.webkit.WebView; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +public class ActivityBrowser extends Activity { + + private final static String TAG = "MusicFXActivityBrowser"; + + /** Called when the activity is first created. */ + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final Intent intent = getIntent(); + final String urlString = intent.getDataString(); + try { + final WebView webView = new WebView(this); + final URL url = new URL(urlString); + new LoadURLTask(webView).execute(url); + } catch (final MalformedURLException e) { + Log.e(TAG, "MalformedURLException " + urlString); + } + } + + /** + * ASync Task that checks if the site is reachable and then loads the URL. + */ + private class LoadURLTask extends AsyncTask<URL, Void, Boolean> { + final WebView mWebView; + String mURLString; + + public LoadURLTask(final WebView webView) { + mWebView = webView; + } + + /* + * (non-Javadoc) + * + * @see android.os.AsyncTask#doInBackground(Params[]) + */ + @Override + protected Boolean doInBackground(final URL... urls) { + + final URL url = urls[0]; + mURLString = url.toString(); + + boolean isSiteReachable = false; + final HttpURLConnection httpURLConnection; + try { + httpURLConnection = (HttpURLConnection) url.openConnection(); + final int response = httpURLConnection.getResponseCode(); + if (response == HttpURLConnection.HTTP_OK) { + isSiteReachable = true; + } + } catch (final IOException e) { + Log.e(TAG, "Error connecting to " + mURLString); + } + return isSiteReachable; + } + + /* + * (non-Javadoc) + * + * @see android.os.AsyncTask#onPostExecute(java.lang.Object) + */ + @Override + protected void onPostExecute(final Boolean isReachable) { + if (isReachable) { + mWebView.setBackgroundColor(Color.BLACK); + setContentView(mWebView); + mWebView.loadUrl(mURLString); + } else { + createAndShowNetworkDialog(); + } + } + } + + /** + * Shows the network dialog alerting the user that the net is down. + */ + private void createAndShowNetworkDialog() { + new AlertDialog.Builder(this).setTitle(R.string.browser_error_dialog_title) + .setMessage(R.string.browser_error_dialog_text) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int which) { + finish(); + } + }).show(); + } +} diff --git a/src/com/android/musicfx/ActivityFirstUse.java b/src/com/android/musicfx/ActivityFirstUse.java index 72f50c9..814ee34 100644 --- a/src/com/android/musicfx/ActivityFirstUse.java +++ b/src/com/android/musicfx/ActivityFirstUse.java @@ -1,96 +1,96 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.musicfx;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.util.Log;
-
-/**
- *
- */
-public class ActivityFirstUse extends Activity {
-
- private final static String TAG = "MusicFXActivityFirstUse";
-
- /**
- * Dialog IDS
- */
- static final int DIALOG_FIRST_USE = 1;
-
- /*
- * (non-Javadoc)
- *
- * @see android.app.Activity#onCreate(android.os.Bundle)
- */
- @Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- showDialog(DIALOG_FIRST_USE);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.app.Activity#onCreateDialog(int)
- */
- @Override
- protected Dialog onCreateDialog(final int id) {
- AlertDialog alertDialog;
- switch (id) {
- case DIALOG_FIRST_USE: {
- final AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage(getString(R.string.first_use_dialog_message));
- builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
-
- @Override
- public void onClick(final DialogInterface dialog, final int which) {
- finish();
- }
- });
- alertDialog = builder.create();
- break;
- }
- default:
- Log.e(TAG, "onCreateDialog invalid Dialog id: " + id);
- alertDialog = null;
- break;
- }
- return alertDialog;
- }
-
- static void checkFirstUse(final Context context, final String packageName) {
- final SharedPreferences prefs = context.getSharedPreferences(packageName, MODE_PRIVATE);
- final String prefsKey = context.getString(R.string.first_use_dailog_shown_key);
- if (!prefs.getBoolean(prefsKey, false)) {
- final Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClass(context, ActivityFirstUse.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
- final SharedPreferences.Editor editor = prefs.edit();
- editor.putBoolean(prefsKey, true);
- editor.commit();
- }
- }
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.musicfx; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; + +/** + * + */ +public class ActivityFirstUse extends Activity { + + private final static String TAG = "MusicFXActivityFirstUse"; + + /** + * Dialog IDS + */ + static final int DIALOG_FIRST_USE = 1; + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onCreate(android.os.Bundle) + */ + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + showDialog(DIALOG_FIRST_USE); + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onCreateDialog(int) + */ + @Override + protected Dialog onCreateDialog(final int id) { + AlertDialog alertDialog; + switch (id) { + case DIALOG_FIRST_USE: { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage(getString(R.string.first_use_dialog_message)); + builder.setPositiveButton(android.R.string.ok, new OnClickListener() { + + @Override + public void onClick(final DialogInterface dialog, final int which) { + finish(); + } + }); + alertDialog = builder.create(); + break; + } + default: + Log.e(TAG, "onCreateDialog invalid Dialog id: " + id); + alertDialog = null; + break; + } + return alertDialog; + } + + static void checkFirstUse(final Context context, final String packageName) { + final SharedPreferences prefs = context.getSharedPreferences(packageName, MODE_PRIVATE); + final String prefsKey = context.getString(R.string.first_use_dailog_shown_key); + if (!prefs.getBoolean(prefsKey, false)) { + final Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClass(context, ActivityFirstUse.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + final SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(prefsKey, true); + editor.commit(); + } + } +} diff --git a/src/com/android/musicfx/ActivityLauncher.java b/src/com/android/musicfx/ActivityLauncher.java index 092053f..372519e 100644 --- a/src/com/android/musicfx/ActivityLauncher.java +++ b/src/com/android/musicfx/ActivityLauncher.java @@ -1,93 +1,93 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.musicfx;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-
-public class ActivityLauncher extends Activity {
-
- Boolean isStopping;
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.launcher);
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- // Inflate the currently selected menu XML resource.
- final MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.options, menu);
-
- return true;
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- isStopping = false;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
-
- // only show the menu if not stopping
- if (!isStopping) {
- openOptionsMenu();
- }
- }
- }, 500);
- }
-
- @Override
- public void onStop() {
- isStopping = true;
- super.onStop();
- }
-
- @Override
- protected Dialog onCreateDialog(final int id) {
- final AlertDialog.Builder builder = Common.createDialog(this);
- builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int whichButton) {
-
- /* User clicked OK so do some stuff */
- openOptionsMenu();
- }
- });
-
- return builder.create();
- }
-
- @Override
- public boolean onOptionsItemSelected(final MenuItem item) {
- Common.handleMenuItem(this, item);
-
- return true;
- }
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.musicfx; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.os.Handler; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +public class ActivityLauncher extends Activity { + + Boolean isStopping; + + /** Called when the activity is first created. */ + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.launcher); + } + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + // Inflate the currently selected menu XML resource. + final MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options, menu); + + return true; + } + + @Override + public void onResume() { + super.onResume(); + + isStopping = false; + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + + // only show the menu if not stopping + if (!isStopping) { + openOptionsMenu(); + } + } + }, 500); + } + + @Override + public void onStop() { + isStopping = true; + super.onStop(); + } + + @Override + protected Dialog onCreateDialog(final int id) { + final AlertDialog.Builder builder = Common.createDialog(this); + builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int whichButton) { + + /* User clicked OK so do some stuff */ + openOptionsMenu(); + } + }); + + return builder.create(); + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + Common.handleMenuItem(this, item); + + return true; + } +} diff --git a/src/com/android/musicfx/ActivityMusic.java b/src/com/android/musicfx/ActivityMusic.java index b8a3a6c..5970b79 100644 --- a/src/com/android/musicfx/ActivityMusic.java +++ b/src/com/android/musicfx/ActivityMusic.java @@ -1,1025 +1,1025 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.musicfx;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.bluetooth.BluetoothClass;
-import android.bluetooth.BluetoothDevice;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.media.audiofx.AudioEffect;
-import android.media.audiofx.AudioEffect.Descriptor;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnTouchListener;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.audiofx.OpenSLESConstants;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- *
- */
-public class ActivityMusic extends Activity implements OnSeekBarChangeListener {
- private final static String TAG = "MusicFXActivityMusic";
-
- /**
- * Max number of EQ bands supported
- */
- private final static int EQUALIZER_MAX_BANDS = 32;
-
- /**
- * Dialog IDS
- */
- static final int DIALOG_EQUALIZER = 0;
- static final int DIALOG_PRESET_REVERB = 1;
- static final int DIALOG_RESET_DEFAULTS = 2;
-
- /**
- * Indicates if Virtualizer effect is supported.
- */
- private boolean mVirtualizerSupported;
- /**
- * Indicates if BassBoost effect is supported.
- */
- private boolean mBassBoostSupported;
- /**
- * Indicates if Equalizer effect is supported.
- */
- private boolean mEqualizerSupported;
- /**
- * Indicates if Preset Reverb effect is supported.
- */
- private boolean mPresetReverbSupported;
-
- // Equalizer fields
- private final SeekBar[] mEqualizerSeekBar = new SeekBar[EQUALIZER_MAX_BANDS];
- private final TextView[] mEqualizerValueText = new TextView[EQUALIZER_MAX_BANDS];
- private int mNumberEqualizerBands;
- private int mEqualizerMinBandLevel;
- private int mEQPresetUserPos = 1;
- private View mEqualizerView;
- private int mEQPreset;
- private int mEQPresetPrevious;
- private int[] mEQPresetUserBandLevelsPrev;
-
- private int mPRPreset;
-
- private boolean mIsHeadsetOn = false;
-
- /**
- * Mapping for the EQ widget ids per band
- */
- private static final int[][] EQViewElementIds = {
- { R.id.EQBand0TextView, R.id.EQBand0SeekBar, R.id.EQBand0Value },
- { R.id.EQBand1TextView, R.id.EQBand1SeekBar, R.id.EQBand1Value },
- { R.id.EQBand2TextView, R.id.EQBand2SeekBar, R.id.EQBand2Value },
- { R.id.EQBand3TextView, R.id.EQBand3SeekBar, R.id.EQBand3Value },
- { R.id.EQBand4TextView, R.id.EQBand4SeekBar, R.id.EQBand4Value },
- { R.id.EQBand5TextView, R.id.EQBand5SeekBar, R.id.EQBand5Value },
- { R.id.EQBand6TextView, R.id.EQBand6SeekBar, R.id.EQBand6Value },
- { R.id.EQBand7TextView, R.id.EQBand7SeekBar, R.id.EQBand7Value },
- { R.id.EQBand8TextView, R.id.EQBand8SeekBar, R.id.EQBand8Value },
- { R.id.EQBand9TextView, R.id.EQBand9SeekBar, R.id.EQBand9Value },
- { R.id.EQBand10TextView, R.id.EQBand10SeekBar, R.id.EQBand10Value },
- { R.id.EQBand11TextView, R.id.EQBand11SeekBar, R.id.EQBand11Value },
- { R.id.EQBand12TextView, R.id.EQBand12SeekBar, R.id.EQBand12Value },
- { R.id.EQBand13TextView, R.id.EQBand13SeekBar, R.id.EQBand13Value },
- { R.id.EQBand14TextView, R.id.EQBand14SeekBar, R.id.EQBand14Value },
- { R.id.EQBand15TextView, R.id.EQBand15SeekBar, R.id.EQBand15Value },
- { R.id.EQBand16TextView, R.id.EQBand16SeekBar, R.id.EQBand16Value },
- { R.id.EQBand17TextView, R.id.EQBand17SeekBar, R.id.EQBand17Value },
- { R.id.EQBand18TextView, R.id.EQBand18SeekBar, R.id.EQBand18Value },
- { R.id.EQBand19TextView, R.id.EQBand19SeekBar, R.id.EQBand19Value },
- { R.id.EQBand20TextView, R.id.EQBand20SeekBar, R.id.EQBand20Value },
- { R.id.EQBand21TextView, R.id.EQBand21SeekBar, R.id.EQBand21Value },
- { R.id.EQBand22TextView, R.id.EQBand22SeekBar, R.id.EQBand22Value },
- { R.id.EQBand23TextView, R.id.EQBand23SeekBar, R.id.EQBand23Value },
- { R.id.EQBand24TextView, R.id.EQBand24SeekBar, R.id.EQBand24Value },
- { R.id.EQBand25TextView, R.id.EQBand25SeekBar, R.id.EQBand25Value },
- { R.id.EQBand26TextView, R.id.EQBand26SeekBar, R.id.EQBand26Value },
- { R.id.EQBand27TextView, R.id.EQBand27SeekBar, R.id.EQBand27Value },
- { R.id.EQBand28TextView, R.id.EQBand28SeekBar, R.id.EQBand28Value },
- { R.id.EQBand29TextView, R.id.EQBand29SeekBar, R.id.EQBand29Value },
- { R.id.EQBand30TextView, R.id.EQBand30SeekBar, R.id.EQBand30Value },
- { R.id.EQBand31TextView, R.id.EQBand31SeekBar, R.id.EQBand31Value } };
-
- // Preset Reverb fields
- /**
- * Array containing the PR preset names.
- */
- private static final String[] PRESETREVERBPRESETSTRINGS = { "None", "SmallRoom", "MediumRoom",
- "LargeRoom", "MediumHall", "LargeHall", "Plate" };
-
- /**
- * Context field
- */
- private Context mContext;
-
- /**
- * Calling package name field
- */
- private String mCallingPackageName = "empty";
-
- /**
- * Audio session field
- */
- private int mAudioSession = AudioEffect.ERROR_BAD_VALUE;
-
- // Broadcast receiver to handle wired and Bluetooth A2dp headset events
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(final Context context, final Intent intent) {
- final String action = intent.getAction();
- final boolean isHeadsetOnPrev = mIsHeadsetOn;
- final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
- mIsHeadsetOn = (intent.getIntExtra("state", 0) == 1)
- || audioManager.isBluetoothA2dpOn();
- } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
- final int deviceClass = ((BluetoothDevice) intent
- .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)).getBluetoothClass()
- .getDeviceClass();
- if ((deviceClass == BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES)
- || (deviceClass == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET)) {
- mIsHeadsetOn = true;
- }
- } else if (action.equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
- mIsHeadsetOn = audioManager.isBluetoothA2dpOn() || audioManager.isWiredHeadsetOn();
- } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
- final int deviceClass = ((BluetoothDevice) intent
- .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)).getBluetoothClass()
- .getDeviceClass();
- if ((deviceClass == BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES)
- || (deviceClass == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET)) {
- mIsHeadsetOn = audioManager.isWiredHeadsetOn();
- }
- }
- if (isHeadsetOnPrev != mIsHeadsetOn) {
- updateUIHeadset();
- }
- }
- };
-
- /*
- * Declares and initializes all objects and widgets in the layouts and the CheckBox and SeekBar
- * onchange methods on creation.
- *
- * (non-Javadoc)
- *
- * @see android.app.ActivityGroup#onCreate(android.os.Bundle)
- */
- @Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Init context to be used in listeners
- mContext = this;
-
- // Receive intent
- // get calling intent
- final Intent intent = getIntent();
- mAudioSession = intent.getIntExtra(AudioEffect.EXTRA_AUDIO_SESSION,
- AudioEffect.ERROR_BAD_VALUE);
- Log.v(TAG, "audio session: " + mAudioSession);
-
- mCallingPackageName = getCallingPackage();
-
- // check for errors
- if (mCallingPackageName == null) {
- Log.e(TAG, "Package name is null");
- setResult(RESULT_CANCELED);
- finish();
- return;
- }
- setResult(RESULT_OK);
-
- Log.v(TAG, mCallingPackageName + " (" + mAudioSession + ")");
-
- ControlPanelEffect.initEffectsPreferences(mContext, mCallingPackageName, mAudioSession);
-
- // query available effects
- final Descriptor[] effects = AudioEffect.queryEffects();
-
- // Determine available/supported effects
- Log.v(TAG, "Available effects:");
- for (final Descriptor effect : effects) {
- Log.v(TAG, effect.name.toString() + ", type: " + effect.type.toString());
-
- if (effect.type.equals(AudioEffect.EFFECT_TYPE_VIRTUALIZER)) {
- mVirtualizerSupported = true;
- } else if (effect.type.equals(AudioEffect.EFFECT_TYPE_BASS_BOOST)) {
- mBassBoostSupported = true;
- } else if (effect.type.equals(AudioEffect.EFFECT_TYPE_EQUALIZER)) {
- mEqualizerSupported = true;
- } else if (effect.type.equals(AudioEffect.EFFECT_TYPE_PRESET_REVERB)) {
- mPresetReverbSupported = true;
- }
- }
-
- setContentView(R.layout.music_main);
- final ViewGroup viewGroup = (ViewGroup) findViewById(R.id.contentSoundEffects);
- final View mainToggleView = findViewById(R.id.mainToggleEffectsLayout);
-
- // Watch for button clicks and initialization.
- if ((mVirtualizerSupported) || (mBassBoostSupported) || (mEqualizerSupported)
- || (mPresetReverbSupported)) {
- // Set the listener for the main enhancements toggle button.
- // Depending on the state enable the supported effects if they were
- // checked in the setup tab.
- final CheckBox toggleEffects = (CheckBox) findViewById(R.id.mainToggleEffectsCheckBox);
- toggleEffects.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(final CompoundButton buttonView,
- final boolean isChecked) {
-
- // set parameter and state
- ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.global_enabled, isChecked);
- // Enable Linear layout (in scroll layout) view with all
- // effect contents depending on checked state
- setEnabledAllChilds(viewGroup, isChecked);
- // update UI according to headset state
- updateUIHeadset();
- }
- });
-
- mainToggleView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(final View v) {
- toggleEffects.toggle();
- }
- });
- ((LinearLayout) findViewById(R.id.mainToggleEffectsLayout)).setVisibility(View.VISIBLE);
-
- // Initialize the Virtualizer elements.
- // Set the SeekBar listener.
- if (mVirtualizerSupported) {
- // Show msg when disabled slider (layout) is touched
- findViewById(R.id.vILayout).setOnTouchListener(new OnTouchListener() {
-
- @Override
- public boolean onTouch(final View v, final MotionEvent event) {
- showHeadsetMsg();
- return false;
- }
- });
-
- final SeekBar seekbar = (SeekBar) findViewById(R.id.vIStrengthSeekBar);
- seekbar.setMax(OpenSLESConstants.VIRTUALIZER_MAX_STRENGTH
- - OpenSLESConstants.VIRTUALIZER_MIN_STRENGTH);
-
- seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
- // Update the parameters while SeekBar changes and set the
- // effect parameter.
-
- @Override
- public void onProgressChanged(final SeekBar seekBar, final int progress,
- final boolean fromUser) {
- // set parameter and state
- ControlPanelEffect.setParameterInt(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.virt_strength, progress);
- }
-
- // If slider pos was 0 when starting re-enable effect
- @Override
- public void onStartTrackingTouch(final SeekBar seekBar) {
- if (seekBar.getProgress() == 0) {
- ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.virt_enabled, true);
- }
- }
-
- // If slider pos = 0 when stopping disable effect
- @Override
- public void onStopTrackingTouch(final SeekBar seekBar) {
- if (seekBar.getProgress() == 0) {
- // disable
- ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.virt_enabled, false);
- }
- }
- });
- }
-
- // Initialize the Bass Boost elements.
- // Set the SeekBar listener.
- if (mBassBoostSupported) {
- // Show msg when disabled slider (layout) is touched
- findViewById(R.id.bBLayout).setOnTouchListener(new OnTouchListener() {
-
- @Override
- public boolean onTouch(final View v, final MotionEvent event) {
- showHeadsetMsg();
- return false;
- }
- });
-
- final SeekBar seekbar = (SeekBar) findViewById(R.id.bBStrengthSeekBar);
- seekbar.setMax(OpenSLESConstants.BASSBOOST_MAX_STRENGTH
- - OpenSLESConstants.BASSBOOST_MIN_STRENGTH);
-
- seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
- // Update the parameters while SeekBar changes and set the
- // effect parameter.
-
- @Override
- public void onProgressChanged(final SeekBar seekBar, final int progress,
- final boolean fromUser) {
- // set parameter and state
- ControlPanelEffect.setParameterInt(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.bb_strength, progress);
- }
-
- // If slider pos was 0 when starting re-enable effect
- @Override
- public void onStartTrackingTouch(final SeekBar seekBar) {
- if (seekBar.getProgress() == 0) {
- ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.bb_enabled, true);
- }
- }
-
- // If slider pos = 0 when stopping disable effect
- @Override
- public void onStopTrackingTouch(final SeekBar seekBar) {
- if (seekBar.getProgress() == 0) {
- // disable
- ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.bb_enabled, false);
- }
-
- }
- });
- }
-
- // Initialize the Equalizer elements.
- if (mEqualizerSupported) {
- final View view = findViewById(R.id.eqLayout);
- view.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(final View v) {
- showDialog(DIALOG_EQUALIZER);
- }
- });
- }
-
- // Initialize the Preset Reverb elements.
- // Set Spinner listeners.
- if (mPresetReverbSupported) {
- final View view = findViewById(R.id.eRLayout);
- view.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(final View v) {
- showDialog(DIALOG_PRESET_REVERB);
- }
- });
- }
-
- // init reset defaults
- final View view = findViewById(R.id.resetDefaultsLayout);
- view.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(final View v) {
- showDialog(DIALOG_RESET_DEFAULTS);
- }
- });
- } else {
- viewGroup.setVisibility(View.GONE);
- mainToggleView.setVisibility(View.GONE);
- ((TextView) findViewById(R.id.noEffectsTextView)).setVisibility(View.VISIBLE);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.app.Activity#onResume()
- */
- @Override
- protected void onResume() {
- super.onResume();
- if ((mVirtualizerSupported) || (mBassBoostSupported) || (mEqualizerSupported)
- || (mPresetReverbSupported)) {
- // Listen for broadcast intents that might affect the onscreen UI for headset.
- final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
- intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
- intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
- intentFilter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
- registerReceiver(mReceiver, intentFilter);
-
- // Check if wired or Bluetooth headset is connected/on
- final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- mIsHeadsetOn = (audioManager.isWiredHeadsetOn() || audioManager.isBluetoothA2dpOn());
- Log.v(TAG, "onResume: mIsHeadsetOn : " + mIsHeadsetOn);
-
- // Update UI
- updateUI();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.app.Activity#onPause()
- */
- @Override
- protected void onPause() {
- super.onPause();
-
- // Unregister for broadcast intents. (These affect the visible UI,
- // so we only care about them while we're in the foreground.)
- unregisterReceiver(mReceiver);
- }
-
- /*
- * Create dialogs for about, EQ preset control, PR and reset to default (alert) dialogs
- *
- * (non-Javadoc)
- *
- * @see android.app.Activity#onCreateDialog(int)
- */
- @Override
- protected Dialog onCreateDialog(final int id) {
- final AlertDialog alertDialog;
- switch (id) {
- case Common.DIALOG_ABOUT: {
- return Common.createDialog(this).create();
- }
- case DIALOG_EQUALIZER: {
- final AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.eq_dialog_title);
- builder.setSingleChoiceItems(getEQPresetStrings(), -1,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int item) {
- if (item != mEQPresetPrevious) {
- equalizerSetPreset(item);
- final ListView listView = ((AlertDialog) dialog).getListView();
- // For the user preset, where EQ sliders need to be shown at the
- // bottom of the list when selected, the footer view of a list is
- // used to display them in.
- // This footer view will then be added or removed from the list
- // depending on whether user preset is selected or not.
- // Using transcript mode to scroll to bottom when in user
- if (!isEqualizerUserPreset(item)) {
- listView.removeFooterView(mEqualizerView);
- listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED);
- } else {
- listView.addFooterView(mEqualizerView);
- listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
- }
- }
- mEQPresetPrevious = item;
- }
- });
- builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int whichButton) {
- final ListView listView = ((AlertDialog) dialog).getListView();
- final int newPreset = listView.getCheckedItemPosition();
- equalizerSetPreset(newPreset);
- ((TextView) findViewById(R.id.eqPresetsTitleTextView))
- .setText(getString(R.string.eq_title) + " "
- + listView.getItemAtPosition(newPreset).toString());
- }
- });
- builder.setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int whichButton) {
- dialog.cancel();
- }
- });
- builder.setOnCancelListener(new OnCancelListener() {
- @Override
- public void onCancel(final DialogInterface dialog) {
- if (!isEqualizerUserPreset(mEQPreset)) {
- final ListView listView = ((AlertDialog) dialog).getListView();
- listView.removeFooterView(mEqualizerView);
- }
- equalizerSetPreset(mEQPreset);
- final int[] presetUserBandLevels = ControlPanelEffect.getParameterIntArray(
- mContext, mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.eq_preset_user_band_level);
- short band = 0;
- for (final int bandLevel : mEQPresetUserBandLevelsPrev) {
- if (bandLevel != presetUserBandLevels[band]) {
- if (!isEqualizerUserPreset(mEQPreset)) {
- ControlPanelEffect.setParameterInt(mContext, mCallingPackageName,
- mAudioSession,
- ControlPanelEffect.Key.eq_preset_user_band_level,
- bandLevel, band);
- } else {
- equalizerBandUpdate(band, (short) bandLevel);
- }
- }
- band++;
- }
- }
- });
-
- alertDialog = builder.create();
- final LayoutInflater factory = LayoutInflater.from(this);
- mEqualizerView = factory.inflate(R.layout.music_eq, null);
- equalizerInit();
- final ListView listView = alertDialog.getListView();
- // Add empty footer view
- listView.addFooterView(mEqualizerView);
-
- mEQPresetUserPos = getEQPresetStrings().length - 1;
- break;
- }
- case DIALOG_PRESET_REVERB: {
- final AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.pr_dialog_title);
- builder.setSingleChoiceItems(PRESETREVERBPRESETSTRINGS, -1,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int item) {
- presetReverbSetPreset(item);
- }
- });
- builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int whichButton) {
- final ListView listView = ((AlertDialog) dialog).getListView();
- final int newPreset = listView.getCheckedItemPosition();
- presetReverbSetPreset(newPreset);
- ((TextView) findViewById(R.id.eRPresetsTitleTextView))
- .setText(getString(R.string.pr_title) + " "
- + listView.getItemAtPosition(newPreset).toString());
- }
- });
- builder.setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int whichButton) {
- dialog.cancel();
- }
- });
- builder.setOnCancelListener(new OnCancelListener() {
- @Override
- public void onCancel(final DialogInterface dialog) {
- presetReverbSetPreset(mPRPreset);
- }
- });
-
- alertDialog = builder.create();
- break;
- }
- case DIALOG_RESET_DEFAULTS: {
- final AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.reset_defaults_dialog_title);
- builder.setMessage(getString(R.string.reset_defaults_dialog_message));
- builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int whichButton) {
- ControlPanelEffect.setEffectDefaults(mContext, mCallingPackageName,
- mAudioSession);
- updateUI();
- }
- });
- builder.setNegativeButton(android.R.string.cancel, null);
- alertDialog = builder.create();
- break;
- }
- default:
- Log.e(TAG, "onCreateDialog invalid Dialog id: " + id);
- alertDialog = null;
- break;
- }
- return alertDialog;
- }
-
- /*
- * Updates dialog (selections) before they are shown if necessary
- *
- * (non-Javadoc)
- *
- * @see android.app.Activity#onPrepareDialog(int, android.app.Dialog, android.os.Bundle)
- */
- @Override
- protected void onPrepareDialog(final int id, final Dialog dialog, final Bundle args) {
- switch (id) {
- case Common.DIALOG_ABOUT: {
- break;
- }
- case DIALOG_EQUALIZER: {
- mEQPreset = ControlPanelEffect.getParameterInt(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.eq_current_preset);
- mEQPresetPrevious = mEQPreset;
- mEQPresetUserBandLevelsPrev = ControlPanelEffect.getParameterIntArray(mContext,
- mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.eq_preset_user_band_level);
- final ListView listView = ((AlertDialog) dialog).getListView();
- listView.setItemChecked(mEQPreset, true);
- listView.setSelection(mEQPreset);
-
- if (isEqualizerUserPreset(mEQPreset)) {
- if (listView.getFooterViewsCount() == 0) {
- listView.addFooterView(mEqualizerView);
- listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
- }
- equalizerUpdateDisplay();
- } else {
- // FIXME: because of a probable bug in Android removeFooterView, we need to catch
- // NPE which is sometimes thrown from inside removeFooterView (encountered only in
- // Honeycomb).
- // Should ideally be be avoided otherwise.
- try {
- listView.removeFooterView(mEqualizerView);
- listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED);
- } catch (final NullPointerException e) {
- Log.w(TAG, "onPrepareDialog: DIALOG_EQUALIZER: removeFooterView: " + e);
- }
- }
-
- break;
- }
- case DIALOG_PRESET_REVERB: {
- mPRPreset = ControlPanelEffect.getParameterInt(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.pr_current_preset);
- final ListView listView = ((AlertDialog) dialog).getListView();
- listView.setItemChecked(mPRPreset, true);
- listView.setSelection(mPRPreset);
- break;
- }
- case DIALOG_RESET_DEFAULTS: {
- break;
- }
- default:
- Log.e(TAG, "onPrepareDialog invalid Dialog id: " + id);
- break;
- }
- }
-
- /**
- * En/disables all childs for a given view. For linear and relative layout childs do this
- * recursively
- *
- * @param view
- * @param enabled
- */
- private void setEnabledAllChilds(final ViewGroup viewGroup, final boolean enabled) {
- final int count = viewGroup.getChildCount();
- for (int i = 0; i < count; i++) {
- final View view = viewGroup.getChildAt(i);
- if ((view instanceof LinearLayout) || (view instanceof RelativeLayout)) {
- final ViewGroup vg = (ViewGroup) view;
- setEnabledAllChilds(vg, enabled);
- }
- view.setEnabled(enabled);
- }
- }
-
- /**
- * Updates UI (checkbox, seekbars, enabled states) according to the current stored preferences.
- */
- private void updateUI() {
- final boolean isEnabled = ControlPanelEffect.getParameterBoolean(mContext,
- mCallingPackageName, mAudioSession, ControlPanelEffect.Key.global_enabled);
- ((CheckBox) findViewById(R.id.mainToggleEffectsCheckBox)).setChecked(isEnabled);
- setEnabledAllChilds((ViewGroup) findViewById(R.id.contentSoundEffects), isEnabled);
- updateUIHeadset();
-
- if (mVirtualizerSupported) {
- ((SeekBar) findViewById(R.id.vIStrengthSeekBar)).setProgress(ControlPanelEffect
- .getParameterInt(mContext, mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.virt_strength));
- }
- if (mBassBoostSupported) {
- ((SeekBar) findViewById(R.id.bBStrengthSeekBar)).setProgress(ControlPanelEffect
- .getParameterInt(mContext, mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.bb_strength));
- }
- if (mEqualizerSupported) {
- ((TextView) findViewById(R.id.eqPresetsTitleTextView))
- .setText(getString(R.string.eq_title)
- + " "
- + getEQPresetStrings()[ControlPanelEffect.getParameterInt(mContext,
- mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.eq_current_preset)]);
- }
- if (mPresetReverbSupported) {
- ((TextView) findViewById(R.id.eRPresetsTitleTextView))
- .setText(getString(R.string.pr_title)
- + " "
- + PRESETREVERBPRESETSTRINGS[ControlPanelEffect.getParameterInt(
- mContext, mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.pr_current_preset)]);
- }
- }
-
- /**
- * Updates UI for headset mode. En/disable VI and BB controls depending on headset state
- * (on/off) if effects are on. Do the inverse for their layouts so they can take over
- * control/events.
- */
- private void updateUIHeadset() {
- if (((CheckBox) findViewById(R.id.mainToggleEffectsCheckBox)).isChecked()) {
- ((TextView) findViewById(R.id.vIStrengthText)).setEnabled(mIsHeadsetOn);
- ((SeekBar) findViewById(R.id.vIStrengthSeekBar)).setEnabled(mIsHeadsetOn);
- findViewById(R.id.vILayout).setEnabled(!mIsHeadsetOn);
- ((TextView) findViewById(R.id.bBStrengthText)).setEnabled(mIsHeadsetOn);
- ((SeekBar) findViewById(R.id.bBStrengthSeekBar)).setEnabled(mIsHeadsetOn);
- findViewById(R.id.bBLayout).setEnabled(!mIsHeadsetOn);
- }
- }
-
- /**
- * Initializes the equalizer elements. Set the SeekBars and Spinner listeners.
- */
- private void equalizerInit() {
- // Initialize the N-Band Equalizer elements.
- mNumberEqualizerBands = ControlPanelEffect.getParameterInt(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.eq_num_bands);
- mEQPresetUserBandLevelsPrev = ControlPanelEffect.getParameterIntArray(mContext,
- mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.eq_preset_user_band_level);
- final int[] centerFreqs = ControlPanelEffect.getParameterIntArray(mContext,
- mCallingPackageName, mAudioSession, ControlPanelEffect.Key.eq_center_freq);
- final int[] bandLevelRange = ControlPanelEffect.getParameterIntArray(mContext,
- mCallingPackageName, mAudioSession, ControlPanelEffect.Key.eq_level_range);
- mEqualizerMinBandLevel = bandLevelRange[0];
- final int mEqualizerMaxBandLevel = bandLevelRange[1];
-
- for (int band = 0; band < mNumberEqualizerBands; band++) {
- // Unit conversion from mHz to Hz and use k prefix if necessary to display
- final int centerFreq = centerFreqs[band] / 1000;
- float centerFreqHz = centerFreq;
- String unitPrefix = "";
- if (centerFreqHz >= 1000) {
- centerFreqHz = centerFreqHz / 1000;
- unitPrefix = "k";
- }
- ((TextView) mEqualizerView.findViewById(EQViewElementIds[band][0])).setText(String
- .format("%.0f ", centerFreqHz) + unitPrefix + "Hz");
- mEqualizerSeekBar[band] = (SeekBar) mEqualizerView
- .findViewById(EQViewElementIds[band][1]);
- mEqualizerSeekBar[band].setMax(mEqualizerMaxBandLevel - mEqualizerMinBandLevel);
- mEqualizerValueText[band] = (TextView) mEqualizerView
- .findViewById(EQViewElementIds[band][2]);
- mEqualizerSeekBar[band].setOnSeekBarChangeListener(this);
- }
-
- // Hide the inactive Equalizer bands.
- for (int band = mNumberEqualizerBands; band < EQUALIZER_MAX_BANDS; band++) {
- // CenterFreq text
- mEqualizerView.findViewById(EQViewElementIds[band][0]).setVisibility(View.GONE);
- // SeekBar
- mEqualizerView.findViewById(EQViewElementIds[band][1]).setVisibility(View.GONE);
- // Value text
- mEqualizerView.findViewById(EQViewElementIds[band][2]).setVisibility(View.GONE);
- }
- }
-
- /*
- * For the EQ Band SeekBars
- *
- * (non-Javadoc)
- *
- * @see android.widget.SeekBar.OnSeekBarChangeListener#onProgressChanged(android
- * .widget.SeekBar, int, boolean)
- */
-
- @Override
- public void onProgressChanged(final SeekBar seekbar, final int progress, final boolean fromUser) {
- final int id = seekbar.getId();
-
- for (short band = 0; band < mNumberEqualizerBands; band++) {
- if (id == EQViewElementIds[band][1]) {
- final short level = (short) (progress + mEqualizerMinBandLevel);
- equalizerBandUpdateDisplay(band, level);
- if (fromUser) {
- equalizerBandUpdate(band, level);
- }
- break;
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.widget.SeekBar.OnSeekBarChangeListener#onStartTrackingTouch(android
- * .widget.SeekBar)
- */
-
- @Override
- public void onStartTrackingTouch(final SeekBar seekbar) {
- // Do nothing
- }
-
- /*
- * Updates the EQ display when the user stops changing.
- *
- * (non-Javadoc)
- *
- * @see android.widget.SeekBar.OnSeekBarChangeListener#onStopTrackingTouch(android
- * .widget.SeekBar)
- */
-
- @Override
- public void onStopTrackingTouch(final SeekBar seekbar) {
- equalizerUpdateDisplay();
- }
-
- /**
- * Updates the EQ by getting the parameters.
- */
- private void equalizerUpdateDisplay() {
- // Update and show the active N-Band Equalizer bands.
- final int[] bandLevels = ControlPanelEffect.getParameterIntArray(mContext,
- mCallingPackageName, mAudioSession, ControlPanelEffect.Key.eq_band_level);
- for (short band = 0; band < mNumberEqualizerBands; band++) {
- final int level = bandLevels[band];
- equalizerBandUpdateDisplay(band, (short) level);
- final int progress = level - mEqualizerMinBandLevel;
- mEqualizerSeekBar[band].setProgress(progress);
- }
- }
-
- /**
- * Updates/sets a given EQ band level.
- *
- * @param band
- * Band id
- * @param level
- * EQ band level
- */
- private void equalizerBandUpdate(final short band, final short level) {
- ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.eq_band_level, level, band);
- }
-
- /**
- * Updates the EQ band level display.
- *
- * @param band
- * Band id
- * @param level
- * EQ band level
- */
- private void equalizerBandUpdateDisplay(final short band, final short level) {
- final int dBValue = level / 100;
- mEqualizerValueText[band].setText(String.format("%d dB", dBValue));
- }
-
- /**
- * Sets the given EQ preset.
- *
- * @param preset
- * EQ preset id.
- */
- private void equalizerSetPreset(final short preset) {
- ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.eq_current_preset, preset);
- if (isEqualizerUserPreset(preset)) {
- equalizerUpdateDisplay();
- }
- }
-
- /**
- * Sets the given EQ preset.
- *
- * @param preset
- * EQ preset id.
- */
- private void equalizerSetPreset(final int preset) {
- equalizerSetPreset((short) preset);
- }
-
- /**
- * Checks if an User EQ preset is set.
- */
- private boolean isEqualizerUserPreset(final int preset) {
- return (preset == mEQPresetUserPos);
- }
-
- /**
- * Gets the EQ preset names
- *
- * @return
- */
- private final String[] getEQPresetStrings() {
- final int numPresets = ControlPanelEffect.getParameterInt(mContext, mCallingPackageName,
- mAudioSession, ControlPanelEffect.Key.eq_num_presets);
- // Fill array with presets from AudioEffects call.
- // allocate a space for 2 extra strings (CI Extreme & User)
- final String[] eQViewPresetStrings = new String[numPresets + 2];
- for (short i = 0; i < numPresets; i++) {
- eQViewPresetStrings[i] = ControlPanelEffect.getParameterString(mContext,
- mCallingPackageName, mAudioSession, ControlPanelEffect.Key.eq_preset_name, i);
- }
-
- eQViewPresetStrings[numPresets] = getString(R.string.ci_extreme);
- eQViewPresetStrings[numPresets + 1] = getString(R.string.user);
- return eQViewPresetStrings;
- }
-
- /**
- * Sets the given PR preset.
- *
- * @param preset
- * PR preset id.
- */
- private void presetReverbSetPreset(final short preset) {
- ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, mAudioSession,
- ControlPanelEffect.Key.pr_current_preset, preset);
- }
-
- /**
- * Sets the given PR preset.
- *
- * @param preset
- * PR preset id.
- */
- private void presetReverbSetPreset(final int preset) {
- presetReverbSetPreset((short) preset);
- }
-
- /**
- * Show msg that headset needs to be plugged.
- */
- private void showHeadsetMsg() {
- final Context context = getApplicationContext();
- final int duration = Toast.LENGTH_SHORT;
-
- final Toast toast = Toast.makeText(context, getString(R.string.headset_plug), duration);
- toast.setGravity(Gravity.CENTER, toast.getXOffset() / 2, toast.getYOffset() / 2);
- toast.show();
- }
-
- /*
- * Creates the options menu
- *
- * (non-Javadoc)
- *
- * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
- */
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- // Inflate the currently selected menu XML resource.
- final MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.options, menu);
-
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
- */
- @Override
- public boolean onOptionsItemSelected(final MenuItem item) {
- Common.handleMenuItem(this, item);
- return true;
- }
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.musicfx; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; +import android.content.Intent; +import android.content.IntentFilter; +import android.media.AudioManager; +import android.media.audiofx.AudioEffect; +import android.media.audiofx.AudioEffect.Descriptor; +import android.os.Bundle; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnTouchListener; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.RelativeLayout; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.audiofx.OpenSLESConstants; + +import java.util.HashMap; +import java.util.Map; + +/** + * + */ +public class ActivityMusic extends Activity implements OnSeekBarChangeListener { + private final static String TAG = "MusicFXActivityMusic"; + + /** + * Max number of EQ bands supported + */ + private final static int EQUALIZER_MAX_BANDS = 32; + + /** + * Dialog IDS + */ + static final int DIALOG_EQUALIZER = 0; + static final int DIALOG_PRESET_REVERB = 1; + static final int DIALOG_RESET_DEFAULTS = 2; + + /** + * Indicates if Virtualizer effect is supported. + */ + private boolean mVirtualizerSupported; + /** + * Indicates if BassBoost effect is supported. + */ + private boolean mBassBoostSupported; + /** + * Indicates if Equalizer effect is supported. + */ + private boolean mEqualizerSupported; + /** + * Indicates if Preset Reverb effect is supported. + */ + private boolean mPresetReverbSupported; + + // Equalizer fields + private final SeekBar[] mEqualizerSeekBar = new SeekBar[EQUALIZER_MAX_BANDS]; + private final TextView[] mEqualizerValueText = new TextView[EQUALIZER_MAX_BANDS]; + private int mNumberEqualizerBands; + private int mEqualizerMinBandLevel; + private int mEQPresetUserPos = 1; + private View mEqualizerView; + private int mEQPreset; + private int mEQPresetPrevious; + private int[] mEQPresetUserBandLevelsPrev; + + private int mPRPreset; + + private boolean mIsHeadsetOn = false; + + /** + * Mapping for the EQ widget ids per band + */ + private static final int[][] EQViewElementIds = { + { R.id.EQBand0TextView, R.id.EQBand0SeekBar, R.id.EQBand0Value }, + { R.id.EQBand1TextView, R.id.EQBand1SeekBar, R.id.EQBand1Value }, + { R.id.EQBand2TextView, R.id.EQBand2SeekBar, R.id.EQBand2Value }, + { R.id.EQBand3TextView, R.id.EQBand3SeekBar, R.id.EQBand3Value }, + { R.id.EQBand4TextView, R.id.EQBand4SeekBar, R.id.EQBand4Value }, + { R.id.EQBand5TextView, R.id.EQBand5SeekBar, R.id.EQBand5Value }, + { R.id.EQBand6TextView, R.id.EQBand6SeekBar, R.id.EQBand6Value }, + { R.id.EQBand7TextView, R.id.EQBand7SeekBar, R.id.EQBand7Value }, + { R.id.EQBand8TextView, R.id.EQBand8SeekBar, R.id.EQBand8Value }, + { R.id.EQBand9TextView, R.id.EQBand9SeekBar, R.id.EQBand9Value }, + { R.id.EQBand10TextView, R.id.EQBand10SeekBar, R.id.EQBand10Value }, + { R.id.EQBand11TextView, R.id.EQBand11SeekBar, R.id.EQBand11Value }, + { R.id.EQBand12TextView, R.id.EQBand12SeekBar, R.id.EQBand12Value }, + { R.id.EQBand13TextView, R.id.EQBand13SeekBar, R.id.EQBand13Value }, + { R.id.EQBand14TextView, R.id.EQBand14SeekBar, R.id.EQBand14Value }, + { R.id.EQBand15TextView, R.id.EQBand15SeekBar, R.id.EQBand15Value }, + { R.id.EQBand16TextView, R.id.EQBand16SeekBar, R.id.EQBand16Value }, + { R.id.EQBand17TextView, R.id.EQBand17SeekBar, R.id.EQBand17Value }, + { R.id.EQBand18TextView, R.id.EQBand18SeekBar, R.id.EQBand18Value }, + { R.id.EQBand19TextView, R.id.EQBand19SeekBar, R.id.EQBand19Value }, + { R.id.EQBand20TextView, R.id.EQBand20SeekBar, R.id.EQBand20Value }, + { R.id.EQBand21TextView, R.id.EQBand21SeekBar, R.id.EQBand21Value }, + { R.id.EQBand22TextView, R.id.EQBand22SeekBar, R.id.EQBand22Value }, + { R.id.EQBand23TextView, R.id.EQBand23SeekBar, R.id.EQBand23Value }, + { R.id.EQBand24TextView, R.id.EQBand24SeekBar, R.id.EQBand24Value }, + { R.id.EQBand25TextView, R.id.EQBand25SeekBar, R.id.EQBand25Value }, + { R.id.EQBand26TextView, R.id.EQBand26SeekBar, R.id.EQBand26Value }, + { R.id.EQBand27TextView, R.id.EQBand27SeekBar, R.id.EQBand27Value }, + { R.id.EQBand28TextView, R.id.EQBand28SeekBar, R.id.EQBand28Value }, + { R.id.EQBand29TextView, R.id.EQBand29SeekBar, R.id.EQBand29Value }, + { R.id.EQBand30TextView, R.id.EQBand30SeekBar, R.id.EQBand30Value }, + { R.id.EQBand31TextView, R.id.EQBand31SeekBar, R.id.EQBand31Value } }; + + // Preset Reverb fields + /** + * Array containing the PR preset names. + */ + private static final String[] PRESETREVERBPRESETSTRINGS = { "None", "SmallRoom", "MediumRoom", + "LargeRoom", "MediumHall", "LargeHall", "Plate" }; + + /** + * Context field + */ + private Context mContext; + + /** + * Calling package name field + */ + private String mCallingPackageName = "empty"; + + /** + * Audio session field + */ + private int mAudioSession = AudioEffect.ERROR_BAD_VALUE; + + // Broadcast receiver to handle wired and Bluetooth A2dp headset events + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(final Context context, final Intent intent) { + final String action = intent.getAction(); + final boolean isHeadsetOnPrev = mIsHeadsetOn; + final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + if (action.equals(Intent.ACTION_HEADSET_PLUG)) { + mIsHeadsetOn = (intent.getIntExtra("state", 0) == 1) + || audioManager.isBluetoothA2dpOn(); + } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { + final int deviceClass = ((BluetoothDevice) intent + .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)).getBluetoothClass() + .getDeviceClass(); + if ((deviceClass == BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES) + || (deviceClass == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET)) { + mIsHeadsetOn = true; + } + } else if (action.equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) { + mIsHeadsetOn = audioManager.isBluetoothA2dpOn() || audioManager.isWiredHeadsetOn(); + } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { + final int deviceClass = ((BluetoothDevice) intent + .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)).getBluetoothClass() + .getDeviceClass(); + if ((deviceClass == BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES) + || (deviceClass == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET)) { + mIsHeadsetOn = audioManager.isWiredHeadsetOn(); + } + } + if (isHeadsetOnPrev != mIsHeadsetOn) { + updateUIHeadset(); + } + } + }; + + /* + * Declares and initializes all objects and widgets in the layouts and the CheckBox and SeekBar + * onchange methods on creation. + * + * (non-Javadoc) + * + * @see android.app.ActivityGroup#onCreate(android.os.Bundle) + */ + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Init context to be used in listeners + mContext = this; + + // Receive intent + // get calling intent + final Intent intent = getIntent(); + mAudioSession = intent.getIntExtra(AudioEffect.EXTRA_AUDIO_SESSION, + AudioEffect.ERROR_BAD_VALUE); + Log.v(TAG, "audio session: " + mAudioSession); + + mCallingPackageName = getCallingPackage(); + + // check for errors + if (mCallingPackageName == null) { + Log.e(TAG, "Package name is null"); + setResult(RESULT_CANCELED); + finish(); + return; + } + setResult(RESULT_OK); + + Log.v(TAG, mCallingPackageName + " (" + mAudioSession + ")"); + + ControlPanelEffect.initEffectsPreferences(mContext, mCallingPackageName, mAudioSession); + + // query available effects + final Descriptor[] effects = AudioEffect.queryEffects(); + + // Determine available/supported effects + Log.v(TAG, "Available effects:"); + for (final Descriptor effect : effects) { + Log.v(TAG, effect.name.toString() + ", type: " + effect.type.toString()); + + if (effect.type.equals(AudioEffect.EFFECT_TYPE_VIRTUALIZER)) { + mVirtualizerSupported = true; + } else if (effect.type.equals(AudioEffect.EFFECT_TYPE_BASS_BOOST)) { + mBassBoostSupported = true; + } else if (effect.type.equals(AudioEffect.EFFECT_TYPE_EQUALIZER)) { + mEqualizerSupported = true; + } else if (effect.type.equals(AudioEffect.EFFECT_TYPE_PRESET_REVERB)) { + mPresetReverbSupported = true; + } + } + + setContentView(R.layout.music_main); + final ViewGroup viewGroup = (ViewGroup) findViewById(R.id.contentSoundEffects); + final View mainToggleView = findViewById(R.id.mainToggleEffectsLayout); + + // Watch for button clicks and initialization. + if ((mVirtualizerSupported) || (mBassBoostSupported) || (mEqualizerSupported) + || (mPresetReverbSupported)) { + // Set the listener for the main enhancements toggle button. + // Depending on the state enable the supported effects if they were + // checked in the setup tab. + final CheckBox toggleEffects = (CheckBox) findViewById(R.id.mainToggleEffectsCheckBox); + toggleEffects.setOnCheckedChangeListener(new OnCheckedChangeListener() { + @Override + public void onCheckedChanged(final CompoundButton buttonView, + final boolean isChecked) { + + // set parameter and state + ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.global_enabled, isChecked); + // Enable Linear layout (in scroll layout) view with all + // effect contents depending on checked state + setEnabledAllChilds(viewGroup, isChecked); + // update UI according to headset state + updateUIHeadset(); + } + }); + + mainToggleView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(final View v) { + toggleEffects.toggle(); + } + }); + ((LinearLayout) findViewById(R.id.mainToggleEffectsLayout)).setVisibility(View.VISIBLE); + + // Initialize the Virtualizer elements. + // Set the SeekBar listener. + if (mVirtualizerSupported) { + // Show msg when disabled slider (layout) is touched + findViewById(R.id.vILayout).setOnTouchListener(new OnTouchListener() { + + @Override + public boolean onTouch(final View v, final MotionEvent event) { + showHeadsetMsg(); + return false; + } + }); + + final SeekBar seekbar = (SeekBar) findViewById(R.id.vIStrengthSeekBar); + seekbar.setMax(OpenSLESConstants.VIRTUALIZER_MAX_STRENGTH + - OpenSLESConstants.VIRTUALIZER_MIN_STRENGTH); + + seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + // Update the parameters while SeekBar changes and set the + // effect parameter. + + @Override + public void onProgressChanged(final SeekBar seekBar, final int progress, + final boolean fromUser) { + // set parameter and state + ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.virt_strength, progress); + } + + // If slider pos was 0 when starting re-enable effect + @Override + public void onStartTrackingTouch(final SeekBar seekBar) { + if (seekBar.getProgress() == 0) { + ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.virt_enabled, true); + } + } + + // If slider pos = 0 when stopping disable effect + @Override + public void onStopTrackingTouch(final SeekBar seekBar) { + if (seekBar.getProgress() == 0) { + // disable + ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.virt_enabled, false); + } + } + }); + } + + // Initialize the Bass Boost elements. + // Set the SeekBar listener. + if (mBassBoostSupported) { + // Show msg when disabled slider (layout) is touched + findViewById(R.id.bBLayout).setOnTouchListener(new OnTouchListener() { + + @Override + public boolean onTouch(final View v, final MotionEvent event) { + showHeadsetMsg(); + return false; + } + }); + + final SeekBar seekbar = (SeekBar) findViewById(R.id.bBStrengthSeekBar); + seekbar.setMax(OpenSLESConstants.BASSBOOST_MAX_STRENGTH + - OpenSLESConstants.BASSBOOST_MIN_STRENGTH); + + seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + // Update the parameters while SeekBar changes and set the + // effect parameter. + + @Override + public void onProgressChanged(final SeekBar seekBar, final int progress, + final boolean fromUser) { + // set parameter and state + ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.bb_strength, progress); + } + + // If slider pos was 0 when starting re-enable effect + @Override + public void onStartTrackingTouch(final SeekBar seekBar) { + if (seekBar.getProgress() == 0) { + ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.bb_enabled, true); + } + } + + // If slider pos = 0 when stopping disable effect + @Override + public void onStopTrackingTouch(final SeekBar seekBar) { + if (seekBar.getProgress() == 0) { + // disable + ControlPanelEffect.setParameterBoolean(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.bb_enabled, false); + } + + } + }); + } + + // Initialize the Equalizer elements. + if (mEqualizerSupported) { + final View view = findViewById(R.id.eqLayout); + view.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(final View v) { + showDialog(DIALOG_EQUALIZER); + } + }); + } + + // Initialize the Preset Reverb elements. + // Set Spinner listeners. + if (mPresetReverbSupported) { + final View view = findViewById(R.id.eRLayout); + view.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(final View v) { + showDialog(DIALOG_PRESET_REVERB); + } + }); + } + + // init reset defaults + final View view = findViewById(R.id.resetDefaultsLayout); + view.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(final View v) { + showDialog(DIALOG_RESET_DEFAULTS); + } + }); + } else { + viewGroup.setVisibility(View.GONE); + mainToggleView.setVisibility(View.GONE); + ((TextView) findViewById(R.id.noEffectsTextView)).setVisibility(View.VISIBLE); + } + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onResume() + */ + @Override + protected void onResume() { + super.onResume(); + if ((mVirtualizerSupported) || (mBassBoostSupported) || (mEqualizerSupported) + || (mPresetReverbSupported)) { + // Listen for broadcast intents that might affect the onscreen UI for headset. + final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG); + intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); + intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); + intentFilter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY); + registerReceiver(mReceiver, intentFilter); + + // Check if wired or Bluetooth headset is connected/on + final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + mIsHeadsetOn = (audioManager.isWiredHeadsetOn() || audioManager.isBluetoothA2dpOn()); + Log.v(TAG, "onResume: mIsHeadsetOn : " + mIsHeadsetOn); + + // Update UI + updateUI(); + } + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onPause() + */ + @Override + protected void onPause() { + super.onPause(); + + // Unregister for broadcast intents. (These affect the visible UI, + // so we only care about them while we're in the foreground.) + unregisterReceiver(mReceiver); + } + + /* + * Create dialogs for about, EQ preset control, PR and reset to default (alert) dialogs + * + * (non-Javadoc) + * + * @see android.app.Activity#onCreateDialog(int) + */ + @Override + protected Dialog onCreateDialog(final int id) { + final AlertDialog alertDialog; + switch (id) { + case Common.DIALOG_ABOUT: { + return Common.createDialog(this).create(); + } + case DIALOG_EQUALIZER: { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.eq_dialog_title); + builder.setSingleChoiceItems(getEQPresetStrings(), -1, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int item) { + if (item != mEQPresetPrevious) { + equalizerSetPreset(item); + final ListView listView = ((AlertDialog) dialog).getListView(); + // For the user preset, where EQ sliders need to be shown at the + // bottom of the list when selected, the footer view of a list is + // used to display them in. + // This footer view will then be added or removed from the list + // depending on whether user preset is selected or not. + // Using transcript mode to scroll to bottom when in user + if (!isEqualizerUserPreset(item)) { + listView.removeFooterView(mEqualizerView); + listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED); + } else { + listView.addFooterView(mEqualizerView); + listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); + } + } + mEQPresetPrevious = item; + } + }); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int whichButton) { + final ListView listView = ((AlertDialog) dialog).getListView(); + final int newPreset = listView.getCheckedItemPosition(); + equalizerSetPreset(newPreset); + ((TextView) findViewById(R.id.eqPresetsTitleTextView)) + .setText(getString(R.string.eq_title) + " " + + listView.getItemAtPosition(newPreset).toString()); + } + }); + builder.setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int whichButton) { + dialog.cancel(); + } + }); + builder.setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(final DialogInterface dialog) { + if (!isEqualizerUserPreset(mEQPreset)) { + final ListView listView = ((AlertDialog) dialog).getListView(); + listView.removeFooterView(mEqualizerView); + } + equalizerSetPreset(mEQPreset); + final int[] presetUserBandLevels = ControlPanelEffect.getParameterIntArray( + mContext, mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.eq_preset_user_band_level); + short band = 0; + for (final int bandLevel : mEQPresetUserBandLevelsPrev) { + if (bandLevel != presetUserBandLevels[band]) { + if (!isEqualizerUserPreset(mEQPreset)) { + ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, + mAudioSession, + ControlPanelEffect.Key.eq_preset_user_band_level, + bandLevel, band); + } else { + equalizerBandUpdate(band, (short) bandLevel); + } + } + band++; + } + } + }); + + alertDialog = builder.create(); + final LayoutInflater factory = LayoutInflater.from(this); + mEqualizerView = factory.inflate(R.layout.music_eq, null); + equalizerInit(); + final ListView listView = alertDialog.getListView(); + // Add empty footer view + listView.addFooterView(mEqualizerView); + + mEQPresetUserPos = getEQPresetStrings().length - 1; + break; + } + case DIALOG_PRESET_REVERB: { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.pr_dialog_title); + builder.setSingleChoiceItems(PRESETREVERBPRESETSTRINGS, -1, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int item) { + presetReverbSetPreset(item); + } + }); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int whichButton) { + final ListView listView = ((AlertDialog) dialog).getListView(); + final int newPreset = listView.getCheckedItemPosition(); + presetReverbSetPreset(newPreset); + ((TextView) findViewById(R.id.eRPresetsTitleTextView)) + .setText(getString(R.string.pr_title) + " " + + listView.getItemAtPosition(newPreset).toString()); + } + }); + builder.setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int whichButton) { + dialog.cancel(); + } + }); + builder.setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(final DialogInterface dialog) { + presetReverbSetPreset(mPRPreset); + } + }); + + alertDialog = builder.create(); + break; + } + case DIALOG_RESET_DEFAULTS: { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.reset_defaults_dialog_title); + builder.setMessage(getString(R.string.reset_defaults_dialog_message)); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int whichButton) { + ControlPanelEffect.setEffectDefaults(mContext, mCallingPackageName, + mAudioSession); + updateUI(); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + alertDialog = builder.create(); + break; + } + default: + Log.e(TAG, "onCreateDialog invalid Dialog id: " + id); + alertDialog = null; + break; + } + return alertDialog; + } + + /* + * Updates dialog (selections) before they are shown if necessary + * + * (non-Javadoc) + * + * @see android.app.Activity#onPrepareDialog(int, android.app.Dialog, android.os.Bundle) + */ + @Override + protected void onPrepareDialog(final int id, final Dialog dialog, final Bundle args) { + switch (id) { + case Common.DIALOG_ABOUT: { + break; + } + case DIALOG_EQUALIZER: { + mEQPreset = ControlPanelEffect.getParameterInt(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.eq_current_preset); + mEQPresetPrevious = mEQPreset; + mEQPresetUserBandLevelsPrev = ControlPanelEffect.getParameterIntArray(mContext, + mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.eq_preset_user_band_level); + final ListView listView = ((AlertDialog) dialog).getListView(); + listView.setItemChecked(mEQPreset, true); + listView.setSelection(mEQPreset); + + if (isEqualizerUserPreset(mEQPreset)) { + if (listView.getFooterViewsCount() == 0) { + listView.addFooterView(mEqualizerView); + listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); + } + equalizerUpdateDisplay(); + } else { + // FIXME: because of a probable bug in Android removeFooterView, we need to catch + // NPE which is sometimes thrown from inside removeFooterView (encountered only in + // Honeycomb). + // Should ideally be be avoided otherwise. + try { + listView.removeFooterView(mEqualizerView); + listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED); + } catch (final NullPointerException e) { + Log.w(TAG, "onPrepareDialog: DIALOG_EQUALIZER: removeFooterView: " + e); + } + } + + break; + } + case DIALOG_PRESET_REVERB: { + mPRPreset = ControlPanelEffect.getParameterInt(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.pr_current_preset); + final ListView listView = ((AlertDialog) dialog).getListView(); + listView.setItemChecked(mPRPreset, true); + listView.setSelection(mPRPreset); + break; + } + case DIALOG_RESET_DEFAULTS: { + break; + } + default: + Log.e(TAG, "onPrepareDialog invalid Dialog id: " + id); + break; + } + } + + /** + * En/disables all childs for a given view. For linear and relative layout childs do this + * recursively + * + * @param view + * @param enabled + */ + private void setEnabledAllChilds(final ViewGroup viewGroup, final boolean enabled) { + final int count = viewGroup.getChildCount(); + for (int i = 0; i < count; i++) { + final View view = viewGroup.getChildAt(i); + if ((view instanceof LinearLayout) || (view instanceof RelativeLayout)) { + final ViewGroup vg = (ViewGroup) view; + setEnabledAllChilds(vg, enabled); + } + view.setEnabled(enabled); + } + } + + /** + * Updates UI (checkbox, seekbars, enabled states) according to the current stored preferences. + */ + private void updateUI() { + final boolean isEnabled = ControlPanelEffect.getParameterBoolean(mContext, + mCallingPackageName, mAudioSession, ControlPanelEffect.Key.global_enabled); + ((CheckBox) findViewById(R.id.mainToggleEffectsCheckBox)).setChecked(isEnabled); + setEnabledAllChilds((ViewGroup) findViewById(R.id.contentSoundEffects), isEnabled); + updateUIHeadset(); + + if (mVirtualizerSupported) { + ((SeekBar) findViewById(R.id.vIStrengthSeekBar)).setProgress(ControlPanelEffect + .getParameterInt(mContext, mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.virt_strength)); + } + if (mBassBoostSupported) { + ((SeekBar) findViewById(R.id.bBStrengthSeekBar)).setProgress(ControlPanelEffect + .getParameterInt(mContext, mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.bb_strength)); + } + if (mEqualizerSupported) { + ((TextView) findViewById(R.id.eqPresetsTitleTextView)) + .setText(getString(R.string.eq_title) + + " " + + getEQPresetStrings()[ControlPanelEffect.getParameterInt(mContext, + mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.eq_current_preset)]); + } + if (mPresetReverbSupported) { + ((TextView) findViewById(R.id.eRPresetsTitleTextView)) + .setText(getString(R.string.pr_title) + + " " + + PRESETREVERBPRESETSTRINGS[ControlPanelEffect.getParameterInt( + mContext, mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.pr_current_preset)]); + } + } + + /** + * Updates UI for headset mode. En/disable VI and BB controls depending on headset state + * (on/off) if effects are on. Do the inverse for their layouts so they can take over + * control/events. + */ + private void updateUIHeadset() { + if (((CheckBox) findViewById(R.id.mainToggleEffectsCheckBox)).isChecked()) { + ((TextView) findViewById(R.id.vIStrengthText)).setEnabled(mIsHeadsetOn); + ((SeekBar) findViewById(R.id.vIStrengthSeekBar)).setEnabled(mIsHeadsetOn); + findViewById(R.id.vILayout).setEnabled(!mIsHeadsetOn); + ((TextView) findViewById(R.id.bBStrengthText)).setEnabled(mIsHeadsetOn); + ((SeekBar) findViewById(R.id.bBStrengthSeekBar)).setEnabled(mIsHeadsetOn); + findViewById(R.id.bBLayout).setEnabled(!mIsHeadsetOn); + } + } + + /** + * Initializes the equalizer elements. Set the SeekBars and Spinner listeners. + */ + private void equalizerInit() { + // Initialize the N-Band Equalizer elements. + mNumberEqualizerBands = ControlPanelEffect.getParameterInt(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.eq_num_bands); + mEQPresetUserBandLevelsPrev = ControlPanelEffect.getParameterIntArray(mContext, + mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.eq_preset_user_band_level); + final int[] centerFreqs = ControlPanelEffect.getParameterIntArray(mContext, + mCallingPackageName, mAudioSession, ControlPanelEffect.Key.eq_center_freq); + final int[] bandLevelRange = ControlPanelEffect.getParameterIntArray(mContext, + mCallingPackageName, mAudioSession, ControlPanelEffect.Key.eq_level_range); + mEqualizerMinBandLevel = bandLevelRange[0]; + final int mEqualizerMaxBandLevel = bandLevelRange[1]; + + for (int band = 0; band < mNumberEqualizerBands; band++) { + // Unit conversion from mHz to Hz and use k prefix if necessary to display + final int centerFreq = centerFreqs[band] / 1000; + float centerFreqHz = centerFreq; + String unitPrefix = ""; + if (centerFreqHz >= 1000) { + centerFreqHz = centerFreqHz / 1000; + unitPrefix = "k"; + } + ((TextView) mEqualizerView.findViewById(EQViewElementIds[band][0])).setText(String + .format("%.0f ", centerFreqHz) + unitPrefix + "Hz"); + mEqualizerSeekBar[band] = (SeekBar) mEqualizerView + .findViewById(EQViewElementIds[band][1]); + mEqualizerSeekBar[band].setMax(mEqualizerMaxBandLevel - mEqualizerMinBandLevel); + mEqualizerValueText[band] = (TextView) mEqualizerView + .findViewById(EQViewElementIds[band][2]); + mEqualizerSeekBar[band].setOnSeekBarChangeListener(this); + } + + // Hide the inactive Equalizer bands. + for (int band = mNumberEqualizerBands; band < EQUALIZER_MAX_BANDS; band++) { + // CenterFreq text + mEqualizerView.findViewById(EQViewElementIds[band][0]).setVisibility(View.GONE); + // SeekBar + mEqualizerView.findViewById(EQViewElementIds[band][1]).setVisibility(View.GONE); + // Value text + mEqualizerView.findViewById(EQViewElementIds[band][2]).setVisibility(View.GONE); + } + } + + /* + * For the EQ Band SeekBars + * + * (non-Javadoc) + * + * @see android.widget.SeekBar.OnSeekBarChangeListener#onProgressChanged(android + * .widget.SeekBar, int, boolean) + */ + + @Override + public void onProgressChanged(final SeekBar seekbar, final int progress, final boolean fromUser) { + final int id = seekbar.getId(); + + for (short band = 0; band < mNumberEqualizerBands; band++) { + if (id == EQViewElementIds[band][1]) { + final short level = (short) (progress + mEqualizerMinBandLevel); + equalizerBandUpdateDisplay(band, level); + if (fromUser) { + equalizerBandUpdate(band, level); + } + break; + } + } + } + + /* + * (non-Javadoc) + * + * @see android.widget.SeekBar.OnSeekBarChangeListener#onStartTrackingTouch(android + * .widget.SeekBar) + */ + + @Override + public void onStartTrackingTouch(final SeekBar seekbar) { + // Do nothing + } + + /* + * Updates the EQ display when the user stops changing. + * + * (non-Javadoc) + * + * @see android.widget.SeekBar.OnSeekBarChangeListener#onStopTrackingTouch(android + * .widget.SeekBar) + */ + + @Override + public void onStopTrackingTouch(final SeekBar seekbar) { + equalizerUpdateDisplay(); + } + + /** + * Updates the EQ by getting the parameters. + */ + private void equalizerUpdateDisplay() { + // Update and show the active N-Band Equalizer bands. + final int[] bandLevels = ControlPanelEffect.getParameterIntArray(mContext, + mCallingPackageName, mAudioSession, ControlPanelEffect.Key.eq_band_level); + for (short band = 0; band < mNumberEqualizerBands; band++) { + final int level = bandLevels[band]; + equalizerBandUpdateDisplay(band, (short) level); + final int progress = level - mEqualizerMinBandLevel; + mEqualizerSeekBar[band].setProgress(progress); + } + } + + /** + * Updates/sets a given EQ band level. + * + * @param band + * Band id + * @param level + * EQ band level + */ + private void equalizerBandUpdate(final short band, final short level) { + ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.eq_band_level, level, band); + } + + /** + * Updates the EQ band level display. + * + * @param band + * Band id + * @param level + * EQ band level + */ + private void equalizerBandUpdateDisplay(final short band, final short level) { + final int dBValue = level / 100; + mEqualizerValueText[band].setText(String.format("%d dB", dBValue)); + } + + /** + * Sets the given EQ preset. + * + * @param preset + * EQ preset id. + */ + private void equalizerSetPreset(final short preset) { + ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.eq_current_preset, preset); + if (isEqualizerUserPreset(preset)) { + equalizerUpdateDisplay(); + } + } + + /** + * Sets the given EQ preset. + * + * @param preset + * EQ preset id. + */ + private void equalizerSetPreset(final int preset) { + equalizerSetPreset((short) preset); + } + + /** + * Checks if an User EQ preset is set. + */ + private boolean isEqualizerUserPreset(final int preset) { + return (preset == mEQPresetUserPos); + } + + /** + * Gets the EQ preset names + * + * @return + */ + private final String[] getEQPresetStrings() { + final int numPresets = ControlPanelEffect.getParameterInt(mContext, mCallingPackageName, + mAudioSession, ControlPanelEffect.Key.eq_num_presets); + // Fill array with presets from AudioEffects call. + // allocate a space for 2 extra strings (CI Extreme & User) + final String[] eQViewPresetStrings = new String[numPresets + 2]; + for (short i = 0; i < numPresets; i++) { + eQViewPresetStrings[i] = ControlPanelEffect.getParameterString(mContext, + mCallingPackageName, mAudioSession, ControlPanelEffect.Key.eq_preset_name, i); + } + + eQViewPresetStrings[numPresets] = getString(R.string.ci_extreme); + eQViewPresetStrings[numPresets + 1] = getString(R.string.user); + return eQViewPresetStrings; + } + + /** + * Sets the given PR preset. + * + * @param preset + * PR preset id. + */ + private void presetReverbSetPreset(final short preset) { + ControlPanelEffect.setParameterInt(mContext, mCallingPackageName, mAudioSession, + ControlPanelEffect.Key.pr_current_preset, preset); + } + + /** + * Sets the given PR preset. + * + * @param preset + * PR preset id. + */ + private void presetReverbSetPreset(final int preset) { + presetReverbSetPreset((short) preset); + } + + /** + * Show msg that headset needs to be plugged. + */ + private void showHeadsetMsg() { + final Context context = getApplicationContext(); + final int duration = Toast.LENGTH_SHORT; + + final Toast toast = Toast.makeText(context, getString(R.string.headset_plug), duration); + toast.setGravity(Gravity.CENTER, toast.getXOffset() / 2, toast.getYOffset() / 2); + toast.show(); + } + + /* + * Creates the options menu + * + * (non-Javadoc) + * + * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) + */ + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + // Inflate the currently selected menu XML resource. + final MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options, menu); + + return true; + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) + */ + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + Common.handleMenuItem(this, item); + return true; + } +} diff --git a/src/com/android/musicfx/Common.java b/src/com/android/musicfx/Common.java index a4d26a5..7e164a1 100644 --- a/src/com/android/musicfx/Common.java +++ b/src/com/android/musicfx/Common.java @@ -1,104 +1,104 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.musicfx;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.Uri;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.TextView;
-
-class Common {
-
- final static int DIALOG_ABOUT = 1000;
-
- static String mVersionName;
-
- static public void handleMenuItem(final Activity context, final MenuItem item) {
- if (item.getTitle().equals(context.getString(R.string.menu_about))) {
- context.showDialog(DIALOG_ABOUT);
- }
-
- if (item.getTitle().equals(context.getString(R.string.menu_help))) {
- final Intent browserIntent = new Intent(null, Uri.parse(context
- .getString(R.string.url_help)));
- browserIntent.setClass(context, ActivityBrowser.class);
- context.startActivity(browserIntent);
- }
-
- if (item.getTitle().equals(context.getString(R.string.menu_feedback))) {
- PackageInfo packageInfo;
- try {
- packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(),
- 0);
- mVersionName = packageInfo.versionName;
- } catch (final NameNotFoundException e) {
- mVersionName = context.getString(R.string.about_version_error);
- }
- final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
- emailIntent.setType("plain/text");
- emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
- new String[] { context.getString(R.string.feedback_email_address) });
- emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
- context.getString(R.string.feedback_email_subject) + " " + mVersionName);
- context.startActivity(Intent.createChooser(emailIntent,
- context.getString(R.string.feedback_email_title)));
- }
-
- if (item.getTitle().equals(context.getString(R.string.menu_developers))) {
- final Intent browserIntent = new Intent(null, Uri.parse(context
- .getString(R.string.url_developers)));
- browserIntent.setClass(context, ActivityBrowser.class);
- context.startActivity(browserIntent);
- }
- }
-
- static public AlertDialog.Builder createDialog(final Activity activity) {
- PackageInfo packageInfo;
- try {
- packageInfo = activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0);
- mVersionName = packageInfo.versionName;
- } catch (final NameNotFoundException e) {
- mVersionName = activity.getString(R.string.about_version_error);
- }
-
- final LayoutInflater factory = LayoutInflater.from(activity);
- final View aboutView = factory.inflate(R.layout.about, null);
-
- final AlertDialog.Builder builder = new AlertDialog.Builder(activity)
- .setIcon(android.R.drawable.ic_menu_info_details).setTitle(R.string.about_title)
- .setView(aboutView)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int whichButton) {
- /* User clicked OK so do some stuff */
- }
- });
-
- final TextView versionTextView = (TextView) aboutView
- .findViewById(R.id.TextViewAboutVersion);
- versionTextView.setText(activity.getString(R.string.about_version) + " " + mVersionName);
-
- return builder;
- }
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.musicfx; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import android.net.Uri; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; + +class Common { + + final static int DIALOG_ABOUT = 1000; + + static String mVersionName; + + static public void handleMenuItem(final Activity context, final MenuItem item) { + if (item.getTitle().equals(context.getString(R.string.menu_about))) { + context.showDialog(DIALOG_ABOUT); + } + + if (item.getTitle().equals(context.getString(R.string.menu_help))) { + final Intent browserIntent = new Intent(null, Uri.parse(context + .getString(R.string.url_help))); + browserIntent.setClass(context, ActivityBrowser.class); + context.startActivity(browserIntent); + } + + if (item.getTitle().equals(context.getString(R.string.menu_feedback))) { + PackageInfo packageInfo; + try { + packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), + 0); + mVersionName = packageInfo.versionName; + } catch (final NameNotFoundException e) { + mVersionName = context.getString(R.string.about_version_error); + } + final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); + emailIntent.setType("plain/text"); + emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, + new String[] { context.getString(R.string.feedback_email_address) }); + emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, + context.getString(R.string.feedback_email_subject) + " " + mVersionName); + context.startActivity(Intent.createChooser(emailIntent, + context.getString(R.string.feedback_email_title))); + } + + if (item.getTitle().equals(context.getString(R.string.menu_developers))) { + final Intent browserIntent = new Intent(null, Uri.parse(context + .getString(R.string.url_developers))); + browserIntent.setClass(context, ActivityBrowser.class); + context.startActivity(browserIntent); + } + } + + static public AlertDialog.Builder createDialog(final Activity activity) { + PackageInfo packageInfo; + try { + packageInfo = activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0); + mVersionName = packageInfo.versionName; + } catch (final NameNotFoundException e) { + mVersionName = activity.getString(R.string.about_version_error); + } + + final LayoutInflater factory = LayoutInflater.from(activity); + final View aboutView = factory.inflate(R.layout.about, null); + + final AlertDialog.Builder builder = new AlertDialog.Builder(activity) + .setIcon(android.R.drawable.ic_menu_info_details).setTitle(R.string.about_title) + .setView(aboutView) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int whichButton) { + /* User clicked OK so do some stuff */ + } + }); + + final TextView versionTextView = (TextView) aboutView + .findViewById(R.id.TextViewAboutVersion); + versionTextView.setText(activity.getString(R.string.about_version) + " " + mVersionName); + + return builder; + } +} diff --git a/src/com/android/musicfx/ControlPanelEffect.java b/src/com/android/musicfx/ControlPanelEffect.java index c2405f9..d8729bd 100644 --- a/src/com/android/musicfx/ControlPanelEffect.java +++ b/src/com/android/musicfx/ControlPanelEffect.java @@ -1,1424 +1,1424 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.musicfx;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.media.MediaPlayer;
-import android.media.audiofx.AudioEffect;
-import android.media.audiofx.BassBoost;
-import android.media.audiofx.Equalizer;
-import android.media.audiofx.PresetReverb;
-import android.media.audiofx.Virtualizer;
-import android.util.Log;
-
-import java.util.Arrays;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * The Common class defines constants to be used by the control panels.
- */
-public class ControlPanelEffect {
-
- private final static String TAG = "MusicFXControlPanelEffect";
-
- /**
- * Audio session priority
- */
- private static final int PRIORITY = 0;
-
- /**
- * The control mode specifies if control panel updates effects and preferences or only
- * preferences.
- */
- static enum ControlMode {
- /**
- * Control panel updates effects and preferences. Applicable when audio session is delivered
- * by user.
- */
- CONTROL_EFFECTS,
- /**
- * Control panel only updates preferences. Applicable when there was no audio or invalid
- * session provided by user.
- */
- CONTROL_PREFERENCES
- }
-
- static enum Key {
- global_enabled, virt_enabled, virt_strength, virt_type, bb_enabled, bb_strength, te_enabled, te_strength, avl_enabled, lm_enabled, lm_strength, eq_enabled, eq_num_bands, eq_level_range, eq_center_freq, eq_band_level, eq_num_presets, eq_preset_name, eq_preset_user_band_level, eq_preset_user_band_level_default, eq_preset_opensl_es_band_level, eq_preset_ci_extreme_band_level, eq_current_preset, pr_enabled, pr_current_preset
- }
-
- // Effect/audio session Mappings
- /**
- * Hashmap initial capacity
- */
- private static final int HASHMAP_INITIAL_CAPACITY = 16;
- /**
- * Hashmap load factor
- */
- private static final float HASHMAP_LOAD_FACTOR = 0.75f;
- /**
- * ConcurrentHashMap concurrency level
- */
- private static final int HASHMAP_CONCURRENCY_LEVEL = 2;
-
- /**
- * Map containing the Virtualizer audio session, effect mappings.
- */
- private static final ConcurrentHashMap<Integer, Virtualizer> mVirtualizerInstances = new ConcurrentHashMap<Integer, Virtualizer>(
- HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
- /**
- * Map containing the BB audio session, effect mappings.
- */
- private static final ConcurrentHashMap<Integer, BassBoost> mBassBoostInstances = new ConcurrentHashMap<Integer, BassBoost>(
- HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
- /**
- * Map containing the EQ audio session, effect mappings.
- */
- private static final ConcurrentHashMap<Integer, Equalizer> mEQInstances = new ConcurrentHashMap<Integer, Equalizer>(
- HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
- /**
- * Map containing the PR audio session, effect mappings.
- */
- private static final ConcurrentHashMap<Integer, PresetReverb> mPresetReverbInstances = new ConcurrentHashMap<Integer, PresetReverb>(
- HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
-
- /**
- * Map containing the package name, audio session mappings.
- */
- private static final ConcurrentHashMap<String, Integer> mPackageSessions = new ConcurrentHashMap<String, Integer>(
- HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
-
- // Defaults
- final static boolean GLOBAL_ENABLED_DEFAULT = true;
- private final static boolean VIRTUALIZER_ENABLED_DEFAULT = true;
- private final static int VIRTUALIZER_STRENGTH_DEFAULT = 1000;
- private final static boolean BASS_BOOST_ENABLED_DEFAULT = true;
- private final static int BASS_BOOST_STRENGTH_DEFAULT = 667;
- private final static boolean PRESET_REVERB_ENABLED_DEFAULT = false;
- private final static int PRESET_REVERB_CURRENT_PRESET_DEFAULT = 0; // None
-
- // EQ defaults
- private final static boolean EQUALIZER_ENABLED_DEFAULT = true;
- private final static String EQUALIZER_PRESET_NAME_DEFAULT = "Preset";
- private final static short EQUALIZER_NUMBER_BANDS_DEFAULT = 5;
- private final static short EQUALIZER_NUMBER_PRESETS_DEFAULT = 0;
- private final static short[] EQUALIZER_BAND_LEVEL_RANGE_DEFAULT = { -1500, 1500 };
- private final static int[] EQUALIZER_CENTER_FREQ_DEFAULT = { 60000, 230000, 910000, 3600000,
- 14000000 };
- private final static short[] EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL = { 0, 800, 400, 100, 1000 };
- private final static short[] EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT = { 0, 0, 0, 0, 0 };
- private final static short[][] EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT = new short[EQUALIZER_NUMBER_PRESETS_DEFAULT][EQUALIZER_NUMBER_BANDS_DEFAULT];
-
- // EQ effect properties which are invariable over all EQ effects sessions
- private static short[] mEQBandLevelRange = EQUALIZER_BAND_LEVEL_RANGE_DEFAULT;
- private static short mEQNumBands = EQUALIZER_NUMBER_BANDS_DEFAULT;
- private static int[] mEQCenterFreq = EQUALIZER_CENTER_FREQ_DEFAULT;
- private static short mEQNumPresets = EQUALIZER_NUMBER_PRESETS_DEFAULT;
- private static short[][] mEQPresetOpenSLESBandLevel = EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT;
- private static String[] mEQPresetNames;
- private static boolean mIsEQInitialized = false;
- private final static Object mEQInitLock = new Object();
-
- /**
- * Default int argument used in methods to see that the arg is a dummy. Used for method
- * overloading.
- */
- private final static int DUMMY_ARGUMENT = -1;
-
- /**
- * Inits effects preferences for the given context and package name in the control panel. If
- * preferences for the given package name don't exist, they are created and initialized.
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- */
- public static void initEffectsPreferences(final Context context, final String packageName,
- final int audioSession) {
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
- final SharedPreferences.Editor editor = prefs.edit();
- final ControlMode controlMode = getControlMode(audioSession);
-
- // init preferences
- try {
- // init global on/off switch
- final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
- GLOBAL_ENABLED_DEFAULT);
- editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled);
- Log.v(TAG, "isGlobalEnabled = " + isGlobalEnabled);
-
- // Virtualizer
- final boolean isVIEnabled = prefs.getBoolean(Key.virt_enabled.toString(),
- VIRTUALIZER_ENABLED_DEFAULT);
- final int vIStrength = prefs.getInt(Key.virt_strength.toString(),
- VIRTUALIZER_STRENGTH_DEFAULT);
- editor.putBoolean(Key.virt_enabled.toString(), isVIEnabled);
- editor.putInt(Key.virt_strength.toString(), vIStrength);
- // BassBoost
- final boolean isBBEnabled = prefs.getBoolean(Key.bb_enabled.toString(),
- BASS_BOOST_ENABLED_DEFAULT);
- final int bBStrength = prefs.getInt(Key.bb_strength.toString(),
- BASS_BOOST_STRENGTH_DEFAULT);
- editor.putBoolean(Key.bb_enabled.toString(), isBBEnabled);
- editor.putInt(Key.bb_strength.toString(), bBStrength);
- // Equalizer
- synchronized (mEQInitLock) {
- // If EQ is not initialized already create "dummy" audio session created by
- // MediaPlayer and create effect on it to retrieve the invariable EQ properties
- if (!mIsEQInitialized) {
- final MediaPlayer mediaPlayer = new MediaPlayer();
- final int session = mediaPlayer.getAudioSessionId();
- Equalizer equalizerEffect = null;
- try {
- Log.d(TAG, "Creating dummy EQ effect");
- equalizerEffect = new Equalizer(PRIORITY, session);
-
- mEQBandLevelRange = equalizerEffect.getBandLevelRange();
- mEQNumBands = equalizerEffect.getNumberOfBands();
- mEQCenterFreq = new int[mEQNumBands];
- for (short band = 0; band < mEQNumBands; band++) {
- mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band);
- }
- mEQNumPresets = equalizerEffect.getNumberOfPresets();
- mEQPresetNames = new String[mEQNumPresets];
- mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands];
- for (short preset = 0; preset < mEQNumPresets; preset++) {
- mEQPresetNames[preset] = equalizerEffect.getPresetName(preset);
- equalizerEffect.usePreset(preset);
- for (short band = 0; band < mEQNumBands; band++) {
- mEQPresetOpenSLESBandLevel[preset][band] = equalizerEffect
- .getBandLevel(band);
- }
- }
-
- mIsEQInitialized = true;
- } catch (final IllegalStateException e) {
- Log.e(TAG, "Equalizer: " + e);
- } catch (final IllegalArgumentException e) {
- Log.e(TAG, "Equalizer: " + e);
- } catch (final UnsupportedOperationException e) {
- Log.e(TAG, "Equalizer: " + e);
- } catch (final RuntimeException e) {
- Log.e(TAG, "Equalizer: " + e);
- } finally {
- if (equalizerEffect != null) {
- equalizerEffect.release();
- }
- mediaPlayer.release();
-
- // When there was a failure set some good defaults
- if (!mIsEQInitialized) {
- mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands];
- for (short preset = 0; preset < mEQNumPresets; preset++) {
- // Init preset names to a dummy name
- mEQPresetNames[preset] = prefs.getString(
- Key.eq_preset_name.toString() + preset,
- EQUALIZER_PRESET_NAME_DEFAULT + preset);
- if (preset < EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT.length) {
- mEQPresetOpenSLESBandLevel[preset] = Arrays.copyOf(
- EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT[preset],
- mEQNumBands);
- }
- }
- }
- }
- }
- editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]);
- editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]);
- editor.putInt(Key.eq_num_bands.toString(), mEQNumBands);
- editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets);
- // Resetting the EQ arrays depending on the real # bands with defaults if
- // band < default size else 0 by copying default arrays over new ones
- final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf(
- EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands);
- final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
- EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
- // If no preset prefs set use CI EXTREME (= numPresets)
- final short eQPreset = (short) prefs.getInt(Key.eq_current_preset.toString(),
- mEQNumPresets);
- editor.putInt(Key.eq_current_preset.toString(), eQPreset);
- final short[] bandLevel = new short[mEQNumBands];
- for (short band = 0; band < mEQNumBands; band++) {
- if (controlMode == ControlMode.CONTROL_PREFERENCES) {
- if (eQPreset < mEQNumPresets) {
- // OpenSL ES effect presets
- bandLevel[band] = mEQPresetOpenSLESBandLevel[eQPreset][band];
- } else if (eQPreset == mEQNumPresets) {
- // CI EXTREME
- bandLevel[band] = eQPresetCIExtremeBandLevel[band];
- } else {
- // User
- bandLevel[band] = (short) prefs.getInt(
- Key.eq_preset_user_band_level.toString() + band,
- eQPresetUserBandLevelDefault[band]);
- }
- editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]);
- }
- editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]);
- editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band,
- eQPresetCIExtremeBandLevel[band]);
- editor.putInt(Key.eq_preset_user_band_level_default.toString() + band,
- eQPresetUserBandLevelDefault[band]);
- }
- for (short preset = 0; preset < mEQNumPresets; preset++) {
- editor.putString(Key.eq_preset_name.toString() + preset, mEQPresetNames[preset]);
- for (short band = 0; band < mEQNumBands; band++) {
- editor.putInt(Key.eq_preset_opensl_es_band_level.toString() + preset + "_"
- + band, mEQPresetOpenSLESBandLevel[preset][band]);
- }
- }
- }
- final boolean isEQEnabled = prefs.getBoolean(Key.eq_enabled.toString(),
- EQUALIZER_ENABLED_DEFAULT);
- editor.putBoolean(Key.eq_enabled.toString(), isEQEnabled);
-
- // Preset reverb
- final boolean isEnabledPR = prefs.getBoolean(Key.pr_enabled.toString(),
- PRESET_REVERB_ENABLED_DEFAULT);
- final short presetPR = (short) prefs.getInt(Key.pr_current_preset.toString(),
- PRESET_REVERB_CURRENT_PRESET_DEFAULT);
- editor.putBoolean(Key.pr_enabled.toString(), isEnabledPR);
- editor.putInt(Key.pr_current_preset.toString(), presetPR);
-
- editor.commit();
- } catch (final RuntimeException e) {
- Log.e(TAG, "initEffectsPreferences: processingEnabled: " + e);
- }
- }
-
- /**
- * Gets the effect control mode based on the given audio session in the control panel. Control
- * mode defines if the control panel is controlling effects and/or preferences
- *
- * @param audioSession
- * System wide unique audio session identifier.
- * @return effect control mode
- */
- public static ControlMode getControlMode(final int audioSession) {
- if (audioSession == AudioEffect.ERROR_BAD_VALUE) {
- return ControlMode.CONTROL_PREFERENCES;
- }
- return ControlMode.CONTROL_EFFECTS;
- }
-
- /**
- * Sets boolean parameter to value for given key
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @param value
- */
- public static void setParameterBoolean(final Context context, final String packageName,
- final int audioSession, final Key key, final boolean value) {
- try {
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
- final ControlMode controlMode = getControlMode(audioSession);
- boolean enabled = value;
-
- // Global on/off
- if (key == Key.global_enabled) {
- boolean processingEnabled = false;
- if (value == true) {
- // enable all with respect to preferences
- if (controlMode == ControlMode.CONTROL_EFFECTS) {
- final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
- if (virtualizerEffect != null) {
- virtualizerEffect.setEnabled(prefs.getBoolean(
- Key.virt_enabled.toString(), VIRTUALIZER_ENABLED_DEFAULT));
- }
- final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
- if (bassBoostEffect != null) {
- bassBoostEffect.setEnabled(prefs.getBoolean(Key.bb_enabled.toString(),
- BASS_BOOST_ENABLED_DEFAULT));
- }
- final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
- if (equalizerEffect != null) {
- equalizerEffect.setEnabled(prefs.getBoolean(Key.eq_enabled.toString(),
- EQUALIZER_ENABLED_DEFAULT));
- }
- // XXX: Preset Reverb not used for the moment, so commented out the effect
- // creation to not use MIPS
- // final PresetReverb presetReverbEffect =
- // getPresetReverbEffect(audioSession);
- // if (presetReverbEffect != null) {
- // presetReverbEffect.setEnabled(prefs.getBoolean(
- // Key.pr_enabled.toString(), PRESET_REVERB_ENABLED_DEFAULT));
- // }
- }
-
- processingEnabled = true;
- Log.v(TAG, "processingEnabled=" + processingEnabled);
-
- } else {
- // disable all
- if (controlMode == ControlMode.CONTROL_EFFECTS) {
- final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
- if (virtualizerEffect != null) {
- virtualizerEffect.setEnabled(false);
- }
- final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
- if (bassBoostEffect != null) {
- bassBoostEffect.setEnabled(false);
- }
- final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
- if (equalizerEffect != null) {
- equalizerEffect.setEnabled(false);
- }
- // XXX: Preset Reverb not used for the moment, so commented out the effect
- // creation to not use MIPS
- // final PresetReverb presetReverbEffect =
- // getPresetReverbEffect(audioSession);
- // if (presetReverbEffect != null) {
- // presetReverbEffect.setEnabled(false);
- // }
- }
-
- processingEnabled = false;
- Log.v(TAG, "processingEnabled=" + processingEnabled);
- }
- enabled = processingEnabled;
- } else if (controlMode == ControlMode.CONTROL_EFFECTS) {
- final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
- GLOBAL_ENABLED_DEFAULT);
- if (isGlobalEnabled == true) {
- // Set effect parameters
- switch (key) {
-
- case global_enabled:
- // Global, already handled, to get out error free
- break;
-
- // Virtualizer
- case virt_enabled:
- final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
- if (virtualizerEffect != null) {
- virtualizerEffect.setEnabled(value);
- enabled = virtualizerEffect.getEnabled();
- }
- break;
-
- // BassBoost
- case bb_enabled:
- final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
- if (bassBoostEffect != null) {
- bassBoostEffect.setEnabled(value);
- enabled = bassBoostEffect.getEnabled();
- }
- break;
-
- // Equalizer
- case eq_enabled:
- final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
- if (equalizerEffect != null) {
- equalizerEffect.setEnabled(value);
- enabled = equalizerEffect.getEnabled();
- }
- break;
-
- // PresetReverb
- case pr_enabled:
- // XXX: Preset Reverb not used for the moment, so commented out the effect
- // creation to not use MIPS
- // final PresetReverb presetReverbEffect =
- // getPresetReverbEffect(audioSession);
- // if (presetReverbEffect != null) {
- // presetReverbEffect.setEnabled(value);
- // enabled = presetReverbEffect.getEnabled();
- // }
- break;
-
- default:
- Log.e(TAG, "Unknown/unsupported key " + key);
- return;
- }
- }
-
- }
-
- // Set preferences
- final SharedPreferences.Editor editor = prefs.edit();
- editor.putBoolean(key.toString(), enabled);
- editor.commit();
-
- } catch (final RuntimeException e) {
- Log.e(TAG, "setParameterBoolean: " + key + "; " + value + "; " + e);
- }
- }
-
- /**
- * Gets boolean parameter for given key
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @return parameter value
- */
- public static Boolean getParameterBoolean(final Context context, final String packageName,
- final int audioSession, final Key key) {
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
- boolean value = false;
-
- try {
- value = prefs.getBoolean(key.toString(), value);
- } catch (final RuntimeException e) {
- Log.e(TAG, "getParameterBoolean: " + key + "; " + value + "; " + e);
- }
-
- return value;
-
- }
-
- /**
- * Sets int parameter for given key and value arg0, arg1
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @param arg0
- * @param arg1
- */
- public static void setParameterInt(final Context context, final String packageName,
- final int audioSession, final Key key, final int arg0, final int arg1) {
- String strKey = key.toString();
- int value = arg0;
-
- try {
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
- final SharedPreferences.Editor editor = prefs.edit();
- final ControlMode controlMode = getControlMode(audioSession);
-
- // Set effect parameters
- if (controlMode == ControlMode.CONTROL_EFFECTS) {
-
- switch (key) {
-
- // Virtualizer
- case virt_strength: {
- final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
- if (virtualizerEffect != null) {
- virtualizerEffect.setStrength((short) value);
- value = virtualizerEffect.getRoundedStrength();
- }
- break;
- }
- // BassBoost
- case bb_strength: {
- final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
- if (bassBoostEffect != null) {
- bassBoostEffect.setStrength((short) value);
- value = bassBoostEffect.getRoundedStrength();
- }
- break;
- }
- // Equalizer
- case eq_band_level: {
- if (arg1 == DUMMY_ARGUMENT) {
- throw new IllegalArgumentException("Dummy arg passed.");
- }
- final short band = (short) arg1;
- strKey = strKey + band;
- final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
- if (equalizerEffect != null) {
- equalizerEffect.setBandLevel(band, (short) value);
- value = equalizerEffect.getBandLevel(band);
- // save band level in User preset
- editor.putInt(Key.eq_preset_user_band_level.toString() + band, value);
- }
- break;
- }
- case eq_current_preset: {
- final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
- if (equalizerEffect != null) {
- final short preset = (short) value;
- final int numBands = prefs.getInt(Key.eq_num_bands.toString(),
- EQUALIZER_NUMBER_BANDS_DEFAULT);
- final int numPresets = prefs.getInt(Key.eq_num_presets.toString(),
- EQUALIZER_NUMBER_PRESETS_DEFAULT);
-
- if (preset < numPresets) {
- // OpenSL ES EQ Effect presets
- equalizerEffect.usePreset(preset);
- value = equalizerEffect.getCurrentPreset();
- } else {
- final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf(
- EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands);
- final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
- EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
- // Set the band levels manually for custom presets
- for (short band = 0; band < numBands; band++) {
- short bandLevel = 0;
- if (preset == numPresets) {
- // CI EXTREME
- bandLevel = (short) prefs.getInt(
- Key.eq_preset_ci_extreme_band_level.toString() + band,
- eQPresetCIExtremeBandLevelDefault[band]);
- } else {
- // User
- bandLevel = (short) prefs.getInt(
- Key.eq_preset_user_band_level.toString() + band,
- eQPresetUserBandLevelDefault[band]);
- }
- equalizerEffect.setBandLevel(band, bandLevel);
- }
- }
-
- // update band levels
- for (short band = 0; band < numBands; band++) {
- final short level = equalizerEffect.getBandLevel(band);
- editor.putInt(Key.eq_band_level.toString() + band, level);
- }
- }
- break;
- }
- case eq_preset_user_band_level:
- // Fall through
- case eq_preset_user_band_level_default:
- // Fall through
- case eq_preset_ci_extreme_band_level: {
- if (arg1 == DUMMY_ARGUMENT) {
- throw new IllegalArgumentException("Dummy arg passed.");
- }
- final short band = (short) arg1;
- strKey = strKey + band;
- break;
- }
- case pr_current_preset:
- // XXX: Preset Reverb not used for the moment, so commented out the effect
- // creation to not use MIPS
- // final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
- // if (presetReverbEffect != null) {
- // presetReverbEffect.setPreset((short) value);
- // value = presetReverbEffect.getPreset();
- // }
- break;
- default:
- Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key);
- return;
- }
- } else {
- switch (key) {
- // Virtualizer
- case virt_strength:
- // Do nothing
- break;
- case virt_type:
- // Do nothing
- break;
-
- // BassBoost
- case bb_strength:
- // Do nothing
- break;
-
- // Equalizer
- case eq_band_level: {
- if (arg1 == DUMMY_ARGUMENT) {
- throw new IllegalArgumentException("Dummy arg passed.");
- }
- final short band = (short) arg1;
- strKey = strKey + band;
-
- editor.putInt(Key.eq_preset_user_band_level.toString() + band, value);
- break;
- }
- case eq_current_preset: {
- final short preset = (short) value;
- final int numBands = prefs.getInt(Key.eq_num_bands.toString(),
- EQUALIZER_NUMBER_BANDS_DEFAULT);
- final int numPresets = prefs.getInt(Key.eq_num_presets.toString(),
- EQUALIZER_NUMBER_PRESETS_DEFAULT);
-
- final short[][] eQPresetOpenSLESBandLevelDefault = Arrays.copyOf(
- EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT, numBands);
- final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf(
- EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands);
- final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
- EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
- for (short band = 0; band < numBands; band++) {
- short bandLevel = 0;
- if (preset < numPresets) {
- // OpenSL ES EQ Effect presets
- bandLevel = (short) prefs.getInt(
- Key.eq_preset_opensl_es_band_level.toString() + preset + "_"
- + band, eQPresetOpenSLESBandLevelDefault[preset][band]);
- } else if (preset == numPresets) {
- // CI EXTREME
- bandLevel = (short) prefs.getInt(
- Key.eq_preset_ci_extreme_band_level.toString() + band,
- eQPresetCIExtremeBandLevelDefault[band]);
- } else {
- // User
- bandLevel = (short) prefs.getInt(
- Key.eq_preset_user_band_level.toString() + band,
- eQPresetUserBandLevelDefault[band]);
- }
- editor.putInt(Key.eq_band_level.toString() + band, bandLevel);
- }
- break;
- }
- case eq_preset_user_band_level:
- // Fall through
- case eq_preset_user_band_level_default:
- // Fall through
- case eq_preset_ci_extreme_band_level: {
- if (arg1 == DUMMY_ARGUMENT) {
- throw new IllegalArgumentException("Dummy arg passed.");
- }
- final short band = (short) arg1;
- strKey = strKey + band;
- break;
- }
- case pr_current_preset:
- // Do nothing
- break;
- default:
- Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key);
- return;
- }
- }
-
- // Set preferences
- editor.putInt(strKey, value);
- editor.commit();
-
- } catch (final RuntimeException e) {
- Log.e(TAG, "setParameterInt: " + key + "; " + arg0 + "; " + arg1 + "; " + e);
- }
-
- }
-
- /**
- * Sets int parameter for given key and value arg
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @param arg
- */
- public static void setParameterInt(final Context context, final String packageName,
- final int audioSession, final Key key, final int arg) {
- setParameterInt(context, packageName, audioSession, key, arg, DUMMY_ARGUMENT);
- }
-
- /**
- * Gets int parameter given key
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @return parameter value
- */
- public static int getParameterInt(final Context context, final String packageName,
- final int audioSession, final String key) {
- int value = 0;
-
- try {
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
- value = prefs.getInt(key, value);
- } catch (final RuntimeException e) {
- Log.e(TAG, "getParameterInt: " + key + "; " + e);
- }
-
- return value;
- }
-
- /**
- * Gets int parameter given key
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @return parameter value
- */
- public static int getParameterInt(final Context context, final String packageName,
- final int audioSession, final Key key) {
- return getParameterInt(context, packageName, audioSession, key.toString());
- }
-
- /**
- * Gets int parameter given key and arg
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param audioSession
- * @param key
- * @param arg
- * @return parameter value
- */
- public static int getParameterInt(final Context context, final String packageName,
- final int audioSession, final Key key, final int arg) {
- return getParameterInt(context, packageName, audioSession, key.toString() + arg);
- }
-
- /**
- * Gets int parameter given key, arg0 and arg1
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param audioSession
- * @param key
- * @param arg0
- * @param arg1
- * @return parameter value
- */
- public static int getParameterInt(final Context context, final String packageName,
- final int audioSession, final Key key, final int arg0, final int arg1) {
- return getParameterInt(context, packageName, audioSession, key.toString() + arg0 + "_"
- + arg1);
- }
-
- /**
- * Gets integer array parameter given key. Returns null if not found.
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @return parameter value array
- */
- public static int[] getParameterIntArray(final Context context, final String packageName,
- final int audioSession, final Key key) {
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
-
- int[] intArray = null;
- try {
- // Get effect parameters
- switch (key) {
- case eq_level_range: {
- intArray = new int[2];
- break;
- }
- case eq_center_freq:
- // Fall through
- case eq_band_level:
- // Fall through
- case eq_preset_user_band_level:
- // Fall through
- case eq_preset_user_band_level_default:
- // Fall through
- case eq_preset_ci_extreme_band_level: {
- final int numBands = prefs.getInt(Key.eq_num_bands.toString(), 0);
- intArray = new int[numBands];
- break;
- }
- default:
- Log.e(TAG, "getParameterIntArray: Unknown/unsupported key " + key);
- return null;
- }
-
- for (int i = 0; i < intArray.length; i++) {
- intArray[i] = prefs.getInt(key.toString() + i, 0);
- }
-
- } catch (final RuntimeException e) {
- Log.e(TAG, "getParameterIntArray: " + key + "; " + e);
- }
-
- return intArray;
- }
-
- /**
- * Gets string parameter given key. Returns empty string if not found.
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @return parameter value
- */
- public static String getParameterString(final Context context, final String packageName,
- final int audioSession, final String key) {
- String value = "";
- try {
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
-
- // Get effect parameters
- value = prefs.getString(key, value);
-
- } catch (final RuntimeException e) {
- Log.e(TAG, "getParameterString: " + key + "; " + e);
- }
-
- return value;
- }
-
- /**
- * Gets string parameter given key.
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param key
- * @return parameter value
- */
- public static String getParameterString(final Context context, final String packageName,
- final int audioSession, final Key key) {
- return getParameterString(context, packageName, audioSession, key.toString());
- }
-
- /**
- * Gets string parameter given key and arg.
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param args
- * @return parameter value
- */
- public static String getParameterString(final Context context, final String packageName,
- final int audioSession, final Key key, final int arg) {
- return getParameterString(context, packageName, audioSession, key.toString() + arg);
- }
-
- /**
- * Opens/initializes the effects session for the given audio session with preferences linked to
- * the given package name and context.
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- */
- public static void openSession(final Context context, final String packageName,
- final int audioSession) {
- Log.v(TAG, "openSession(" + context + ", " + packageName + ", " + audioSession + ")");
- final String methodTag = "openSession: ";
-
- // init preferences
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
- final SharedPreferences.Editor editor = prefs.edit();
-
- final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
- GLOBAL_ENABLED_DEFAULT);
- editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled);
-
- // Manage audioSession information
-
- // Retrieve AudioSession Id from map
- boolean isExistingAudioSession = false;
-
- try {
- final Integer currentAudioSession = mPackageSessions.putIfAbsent(packageName,
- audioSession);
- if (currentAudioSession != null) {
- // Compare with passed argument
- if (currentAudioSession == audioSession) {
- // FIXME: Normally, we should exit the function here
- // BUT: we have to take care of the virtualizer because of
- // a bug in the Android Effects Framework
- // editor.commit();
- // return;
- isExistingAudioSession = true;
- } else {
- closeSession(context, packageName, currentAudioSession);
- }
- }
- } catch (final NullPointerException e) {
- Log.e(TAG, methodTag + e);
- editor.commit();
- return;
- }
-
- // Because the audioSession is new, get effects & settings from shared preferences
-
- // Virtualizer
- // create effect
- final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
- {
- final String errorTag = methodTag + "Virtualizer error: ";
-
- try {
- // read parameters
- final boolean isEnabled = prefs.getBoolean(Key.virt_enabled.toString(),
- VIRTUALIZER_ENABLED_DEFAULT);
- final int strength = prefs.getInt(Key.virt_strength.toString(),
- VIRTUALIZER_STRENGTH_DEFAULT);
- // init settings
- Virtualizer.Settings settings = new Virtualizer.Settings("Virtualizer;strength="
- + strength);
-
- virtualizerEffect.setProperties(settings);
-
- // set parameters
- if (isGlobalEnabled == true) {
- virtualizerEffect.setEnabled(isEnabled);
- } else {
- virtualizerEffect.setEnabled(false);
- }
-
- // get parameters
- settings = virtualizerEffect.getProperties();
- Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
-
- // update preferences
- editor.putBoolean(Key.virt_enabled.toString(), isEnabled);
- editor.putInt(Key.virt_strength.toString(), settings.strength);
- } catch (final RuntimeException e) {
- Log.e(TAG, errorTag + e);
- }
- }
-
- // In case of an existing audio session
- // Exit after the virtualizer has been re-enabled
-
- if (isExistingAudioSession) {
- editor.commit();
- return;
- }
-
- // BassBoost
- // create effect
- final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
- {
- final String errorTag = methodTag + "BassBoost error: ";
-
- try {
- // read parameters
- final boolean isEnabled = prefs.getBoolean(Key.bb_enabled.toString(),
- BASS_BOOST_ENABLED_DEFAULT);
- final int strength = prefs.getInt(Key.bb_strength.toString(),
- BASS_BOOST_STRENGTH_DEFAULT);
-
- // init settings
- BassBoost.Settings settings = new BassBoost.Settings("BassBoost;strength="
- + strength);
-
- bassBoostEffect.setProperties(settings);
-
- // set parameters
- if (isGlobalEnabled == true) {
- bassBoostEffect.setEnabled(isEnabled);
- } else {
- bassBoostEffect.setEnabled(false);
- }
-
- // get parameters
- settings = bassBoostEffect.getProperties();
- Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
-
- // update preferences
- editor.putBoolean(Key.bb_enabled.toString(), isEnabled);
- editor.putInt(Key.bb_strength.toString(), settings.strength);
- } catch (final RuntimeException e) {
- Log.e(TAG, errorTag + e);
- }
- }
-
- // Equalizer
- // create effect
- final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
- {
- final String errorTag = methodTag + "Equalizer error: ";
-
- try {
- final short eQNumBands;
- final short[] bandLevel;
- final int[] eQCenterFreq;
- final short eQNumPresets;
- final String[] eQPresetNames;
- short eQPreset;
- synchronized (mEQInitLock) {
- // read parameters
- mEQBandLevelRange = equalizerEffect.getBandLevelRange();
- mEQNumBands = equalizerEffect.getNumberOfBands();
- mEQCenterFreq = new int[mEQNumBands];
- mEQNumPresets = equalizerEffect.getNumberOfPresets();
- mEQPresetNames = new String[mEQNumPresets];
-
- for (short preset = 0; preset < mEQNumPresets; preset++) {
- mEQPresetNames[preset] = equalizerEffect.getPresetName(preset);
- editor.putString(Key.eq_preset_name.toString() + preset,
- mEQPresetNames[preset]);
- }
-
- editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]);
- editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]);
- editor.putInt(Key.eq_num_bands.toString(), mEQNumBands);
- editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets);
- // Resetting the EQ arrays depending on the real # bands with defaults if band <
- // default size else 0 by copying default arrays over new ones
- final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf(
- EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands);
- final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
- EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
- // If no preset prefs set use CI EXTREME (= numPresets)
- eQPreset = (short) prefs
- .getInt(Key.eq_current_preset.toString(), mEQNumPresets);
- if (eQPreset < mEQNumPresets) {
- // OpenSL ES effect presets
- equalizerEffect.usePreset(eQPreset);
- eQPreset = equalizerEffect.getCurrentPreset();
- } else {
- for (short band = 0; band < mEQNumBands; band++) {
- short level = 0;
- if (eQPreset == mEQNumPresets) {
- // CI EXTREME
- level = eQPresetCIExtremeBandLevel[band];
- } else {
- // User
- level = (short) prefs.getInt(
- Key.eq_preset_user_band_level.toString() + band,
- eQPresetUserBandLevelDefault[band]);
- }
- equalizerEffect.setBandLevel(band, level);
- }
- }
- editor.putInt(Key.eq_current_preset.toString(), eQPreset);
-
- bandLevel = new short[mEQNumBands];
- for (short band = 0; band < mEQNumBands; band++) {
- mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band);
- bandLevel[band] = equalizerEffect.getBandLevel(band);
-
- editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]);
- editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]);
- editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band,
- eQPresetCIExtremeBandLevel[band]);
- editor.putInt(Key.eq_preset_user_band_level_default.toString() + band,
- eQPresetUserBandLevelDefault[band]);
- }
-
- eQNumBands = mEQNumBands;
- eQCenterFreq = mEQCenterFreq;
- eQNumPresets = mEQNumPresets;
- eQPresetNames = mEQPresetNames;
- }
-
- final boolean isEnabled = prefs.getBoolean(Key.eq_enabled.toString(),
- EQUALIZER_ENABLED_DEFAULT);
- editor.putBoolean(Key.eq_enabled.toString(), isEnabled);
- if (isGlobalEnabled == true) {
- equalizerEffect.setEnabled(isEnabled);
- } else {
- equalizerEffect.setEnabled(false);
- }
-
- // dump
- Log.v(TAG, "Parameters: Equalizer");
- Log.v(TAG, "bands=" + eQNumBands);
- String str = "levels=";
- for (short band = 0; band < eQNumBands; band++) {
- str = str + bandLevel[band] + "; ";
- }
- Log.v(TAG, str);
- str = "center=";
- for (short band = 0; band < eQNumBands; band++) {
- str = str + eQCenterFreq[band] + "; ";
- }
- Log.v(TAG, str);
- str = "presets=";
- for (short preset = 0; preset < eQNumPresets; preset++) {
- str = str + eQPresetNames[preset] + "; ";
- }
- Log.v(TAG, str);
- Log.v(TAG, "current=" + eQPreset);
- } catch (final RuntimeException e) {
- Log.e(TAG, errorTag + e);
- }
- }
-
- // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not
- // use MIPS left in the code for (future) reference.
- // Preset reverb
- // create effect
- // final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
- // {
- // final String errorTag = methodTag + "PresetReverb error: ";
- //
- // try {
- // // read parameters
- // final boolean isEnabled = prefs.getBoolean(Key.pr_enabled.toString(),
- // PRESET_REVERB_ENABLED_DEFAULT);
- // final short preset = (short) prefs.getInt(Key.pr_current_preset.toString(),
- // PRESET_REVERB_CURRENT_PRESET_DEFAULT);
- //
- // // init settings
- // PresetReverb.Settings settings = new PresetReverb.Settings("PresetReverb;preset="
- // + preset);
- //
- // // read/update preferences
- // presetReverbEffect.setProperties(settings);
- //
- // // set parameters
- // if (isGlobalEnabled == true) {
- // presetReverbEffect.setEnabled(isEnabled);
- // } else {
- // presetReverbEffect.setEnabled(false);
- // }
- //
- // // get parameters
- // settings = presetReverbEffect.getProperties();
- // Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
- //
- // // update preferences
- // editor.putBoolean(Key.pr_enabled.toString(), isEnabled);
- // editor.putInt(Key.pr_current_preset.toString(), settings.preset);
- // } catch (final RuntimeException e) {
- // Log.e(TAG, errorTag + e);
- // }
- // }
- editor.commit();
- }
-
- /**
- * Closes the audio session (release effects) for the given session
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- */
- public static void closeSession(final Context context, final String packageName,
- final int audioSession) {
- Log.v(TAG, "closeSession(" + context + ", " + packageName + ", " + audioSession + ")");
-
- // PresetReverb
- final PresetReverb presetReverb = mPresetReverbInstances.remove(audioSession);
- if (presetReverb != null) {
- presetReverb.release();
- }
- // Equalizer
- final Equalizer equalizer = mEQInstances.remove(audioSession);
- if (equalizer != null) {
- equalizer.release();
- }
- // BassBoost
- final BassBoost bassBoost = mBassBoostInstances.remove(audioSession);
- if (bassBoost != null) {
- bassBoost.release();
- }
- // Virtualizer
- final Virtualizer virtualizer = mVirtualizerInstances.remove(audioSession);
- if (virtualizer != null) {
- virtualizer.release();
- }
-
- mPackageSessions.remove(packageName);
- }
-
- /**
- * Enables or disables all effects (global enable/disable) for a given context, package name and
- * audio session. It sets/inits the control mode and preferences and then sets the global
- * enabled parameter.
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- * @param enabled
- */
- public static void setEnabledAll(final Context context, final String packageName,
- final int audioSession, final boolean enabled) {
- initEffectsPreferences(context, packageName, audioSession);
- setParameterBoolean(context, packageName, audioSession, Key.global_enabled, enabled);
- }
-
- /**
- * Sets the defaults for all effects.
- *
- * @param context
- * @param packageName
- * @param audioSession
- * System wide unique audio session identifier.
- */
- public static void setEffectDefaults(final Context context, final String packageName,
- final int audioSession) {
- final SharedPreferences prefs = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE);
- final SharedPreferences.Editor editor = prefs.edit();
-
- setParameterBoolean(context, packageName, audioSession, Key.global_enabled,
- GLOBAL_ENABLED_DEFAULT);
- setParameterBoolean(context, packageName, audioSession, Key.virt_enabled,
- VIRTUALIZER_ENABLED_DEFAULT);
- setParameterInt(context, packageName, audioSession, Key.virt_strength,
- VIRTUALIZER_STRENGTH_DEFAULT);
- setParameterBoolean(context, packageName, audioSession, Key.bb_enabled,
- BASS_BOOST_ENABLED_DEFAULT);
- setParameterInt(context, packageName, audioSession, Key.bb_strength,
- BASS_BOOST_STRENGTH_DEFAULT);
- setParameterBoolean(context, packageName, audioSession, Key.eq_enabled,
- EQUALIZER_ENABLED_DEFAULT);
- // CI preset idx = numPresets
- final int numPresets = prefs.getInt(Key.eq_num_presets.toString(), EQUALIZER_NUMBER_PRESETS_DEFAULT);
- setParameterInt(context, packageName, audioSession, Key.eq_current_preset, numPresets);
- // Reset User EQ levels
- final int numBands = prefs.getInt(Key.eq_num_bands.toString(), EQUALIZER_NUMBER_BANDS_DEFAULT);
- final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
- EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
- for (short band = 0; band < numBands; band++) {
- editor.putInt(Key.eq_preset_user_band_level.toString() + band,
- eQPresetUserBandLevelDefault[band]);
- }
- setParameterBoolean(context, packageName, numBands, Key.pr_enabled,
- PRESET_REVERB_ENABLED_DEFAULT);
- setParameterInt(context, packageName, numBands, Key.pr_current_preset,
- PRESET_REVERB_CURRENT_PRESET_DEFAULT);
- editor.commit();
- }
-
- /**
- * Gets the virtualizer effect for the given audio session. If the effect on the session doesn't
- * exist yet, create it and add to collection.
- *
- * @param audioSession
- * System wide unique audio session identifier.
- * @return virtualizerEffect
- */
- private static Virtualizer getVirtualizerEffect(final int audioSession) {
- Virtualizer virtualizerEffect = mVirtualizerInstances.get(audioSession);
- if (virtualizerEffect == null) {
- try {
- final Virtualizer newVirtualizerEffect = new Virtualizer(PRIORITY, audioSession);
- virtualizerEffect = mVirtualizerInstances.putIfAbsent(audioSession,
- newVirtualizerEffect);
- if (virtualizerEffect == null) {
- // put succeeded, use new value
- virtualizerEffect = newVirtualizerEffect;
- }
- } catch (final IllegalArgumentException e) {
- Log.e(TAG, "Virtualizer: " + e);
- } catch (final UnsupportedOperationException e) {
- Log.e(TAG, "Virtualizer: " + e);
- } catch (final RuntimeException e) {
- Log.e(TAG, "Virtualizer: " + e);
- }
- }
- return virtualizerEffect;
- }
-
- /**
- * Gets the bass boost effect for the given audio session. If the effect on the session doesn't
- * exist yet, create it and add to collection.
- *
- * @param audioSession
- * System wide unique audio session identifier.
- * @return bassBoostEffect
- */
- private static BassBoost getBassBoostEffect(final int audioSession) {
- BassBoost bassBoostEffect = mBassBoostInstances.get(audioSession);
- if (bassBoostEffect == null) {
- try {
- final BassBoost newBassBoostEffect = new BassBoost(PRIORITY, audioSession);
- bassBoostEffect = mBassBoostInstances.putIfAbsent(audioSession, newBassBoostEffect);
- if (bassBoostEffect == null) {
- // put succeeded, use new value
- bassBoostEffect = newBassBoostEffect;
- }
- } catch (final IllegalArgumentException e) {
- Log.e(TAG, "BassBoost: " + e);
- } catch (final UnsupportedOperationException e) {
- Log.e(TAG, "BassBoost: " + e);
- } catch (final RuntimeException e) {
- Log.e(TAG, "BassBoost: " + e);
- }
- }
- return bassBoostEffect;
- }
-
- /**
- * Gets the equalizer effect for the given audio session. If the effect on the session doesn't
- * exist yet, create it and add to collection.
- *
- * @param audioSession
- * System wide unique audio session identifier.
- * @return equalizerEffect
- */
- private static Equalizer getEqualizerEffect(final int audioSession) {
- Equalizer equalizerEffect = mEQInstances.get(audioSession);
- if (equalizerEffect == null) {
- try {
- final Equalizer newEqualizerEffect = new Equalizer(PRIORITY, audioSession);
- equalizerEffect = mEQInstances.putIfAbsent(audioSession, newEqualizerEffect);
- if (equalizerEffect == null) {
- // put succeeded, use new value
- equalizerEffect = newEqualizerEffect;
- }
- } catch (final IllegalArgumentException e) {
- Log.e(TAG, "Equalizer: " + e);
- } catch (final UnsupportedOperationException e) {
- Log.e(TAG, "Equalizer: " + e);
- } catch (final RuntimeException e) {
- Log.e(TAG, "Equalizer: " + e);
- }
- }
- return equalizerEffect;
- }
-
- // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not
- // use MIPS
- // /**
- // * Gets the preset reverb effect for the given audio session. If the effect on the session
- // * doesn't exist yet, create it and add to collection.
- // *
- // * @param audioSession
- // * System wide unique audio session identifier.
- // * @return presetReverbEffect
- // */
- // private static PresetReverb getPresetReverbEffect(final int audioSession) {
- // PresetReverb presetReverbEffect = mPresetReverbInstances.get(audioSession);
- // if (presetReverbEffect == null) {
- // try {
- // final PresetReverb newPresetReverbEffect = new PresetReverb(PRIORITY, audioSession);
- // presetReverbEffect = mPresetReverbInstances.putIfAbsent(audioSession,
- // newPresetReverbEffect);
- // if (presetReverbEffect == null) {
- // // put succeeded, use new value
- // presetReverbEffect = newPresetReverbEffect;
- // }
- // } catch (final IllegalArgumentException e) {
- // Log.e(TAG, "PresetReverb: " + e);
- // } catch (final UnsupportedOperationException e) {
- // Log.e(TAG, "PresetReverb: " + e);
- // } catch (final RuntimeException e) {
- // Log.e(TAG, "PresetReverb: " + e);
- // }
- // }
- // return presetReverbEffect;
- // }
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.musicfx; + +import android.content.Context; +import android.content.SharedPreferences; +import android.media.MediaPlayer; +import android.media.audiofx.AudioEffect; +import android.media.audiofx.BassBoost; +import android.media.audiofx.Equalizer; +import android.media.audiofx.PresetReverb; +import android.media.audiofx.Virtualizer; +import android.util.Log; + +import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; + +/** + * The Common class defines constants to be used by the control panels. + */ +public class ControlPanelEffect { + + private final static String TAG = "MusicFXControlPanelEffect"; + + /** + * Audio session priority + */ + private static final int PRIORITY = 0; + + /** + * The control mode specifies if control panel updates effects and preferences or only + * preferences. + */ + static enum ControlMode { + /** + * Control panel updates effects and preferences. Applicable when audio session is delivered + * by user. + */ + CONTROL_EFFECTS, + /** + * Control panel only updates preferences. Applicable when there was no audio or invalid + * session provided by user. + */ + CONTROL_PREFERENCES + } + + static enum Key { + global_enabled, virt_enabled, virt_strength, virt_type, bb_enabled, bb_strength, te_enabled, te_strength, avl_enabled, lm_enabled, lm_strength, eq_enabled, eq_num_bands, eq_level_range, eq_center_freq, eq_band_level, eq_num_presets, eq_preset_name, eq_preset_user_band_level, eq_preset_user_band_level_default, eq_preset_opensl_es_band_level, eq_preset_ci_extreme_band_level, eq_current_preset, pr_enabled, pr_current_preset + } + + // Effect/audio session Mappings + /** + * Hashmap initial capacity + */ + private static final int HASHMAP_INITIAL_CAPACITY = 16; + /** + * Hashmap load factor + */ + private static final float HASHMAP_LOAD_FACTOR = 0.75f; + /** + * ConcurrentHashMap concurrency level + */ + private static final int HASHMAP_CONCURRENCY_LEVEL = 2; + + /** + * Map containing the Virtualizer audio session, effect mappings. + */ + private static final ConcurrentHashMap<Integer, Virtualizer> mVirtualizerInstances = new ConcurrentHashMap<Integer, Virtualizer>( + HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL); + /** + * Map containing the BB audio session, effect mappings. + */ + private static final ConcurrentHashMap<Integer, BassBoost> mBassBoostInstances = new ConcurrentHashMap<Integer, BassBoost>( + HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL); + /** + * Map containing the EQ audio session, effect mappings. + */ + private static final ConcurrentHashMap<Integer, Equalizer> mEQInstances = new ConcurrentHashMap<Integer, Equalizer>( + HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL); + /** + * Map containing the PR audio session, effect mappings. + */ + private static final ConcurrentHashMap<Integer, PresetReverb> mPresetReverbInstances = new ConcurrentHashMap<Integer, PresetReverb>( + HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL); + + /** + * Map containing the package name, audio session mappings. + */ + private static final ConcurrentHashMap<String, Integer> mPackageSessions = new ConcurrentHashMap<String, Integer>( + HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL); + + // Defaults + final static boolean GLOBAL_ENABLED_DEFAULT = true; + private final static boolean VIRTUALIZER_ENABLED_DEFAULT = true; + private final static int VIRTUALIZER_STRENGTH_DEFAULT = 1000; + private final static boolean BASS_BOOST_ENABLED_DEFAULT = true; + private final static int BASS_BOOST_STRENGTH_DEFAULT = 667; + private final static boolean PRESET_REVERB_ENABLED_DEFAULT = false; + private final static int PRESET_REVERB_CURRENT_PRESET_DEFAULT = 0; // None + + // EQ defaults + private final static boolean EQUALIZER_ENABLED_DEFAULT = true; + private final static String EQUALIZER_PRESET_NAME_DEFAULT = "Preset"; + private final static short EQUALIZER_NUMBER_BANDS_DEFAULT = 5; + private final static short EQUALIZER_NUMBER_PRESETS_DEFAULT = 0; + private final static short[] EQUALIZER_BAND_LEVEL_RANGE_DEFAULT = { -1500, 1500 }; + private final static int[] EQUALIZER_CENTER_FREQ_DEFAULT = { 60000, 230000, 910000, 3600000, + 14000000 }; + private final static short[] EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL = { 0, 800, 400, 100, 1000 }; + private final static short[] EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT = { 0, 0, 0, 0, 0 }; + private final static short[][] EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT = new short[EQUALIZER_NUMBER_PRESETS_DEFAULT][EQUALIZER_NUMBER_BANDS_DEFAULT]; + + // EQ effect properties which are invariable over all EQ effects sessions + private static short[] mEQBandLevelRange = EQUALIZER_BAND_LEVEL_RANGE_DEFAULT; + private static short mEQNumBands = EQUALIZER_NUMBER_BANDS_DEFAULT; + private static int[] mEQCenterFreq = EQUALIZER_CENTER_FREQ_DEFAULT; + private static short mEQNumPresets = EQUALIZER_NUMBER_PRESETS_DEFAULT; + private static short[][] mEQPresetOpenSLESBandLevel = EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT; + private static String[] mEQPresetNames; + private static boolean mIsEQInitialized = false; + private final static Object mEQInitLock = new Object(); + + /** + * Default int argument used in methods to see that the arg is a dummy. Used for method + * overloading. + */ + private final static int DUMMY_ARGUMENT = -1; + + /** + * Inits effects preferences for the given context and package name in the control panel. If + * preferences for the given package name don't exist, they are created and initialized. + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + */ + public static void initEffectsPreferences(final Context context, final String packageName, + final int audioSession) { + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + final SharedPreferences.Editor editor = prefs.edit(); + final ControlMode controlMode = getControlMode(audioSession); + + // init preferences + try { + // init global on/off switch + final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(), + GLOBAL_ENABLED_DEFAULT); + editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled); + Log.v(TAG, "isGlobalEnabled = " + isGlobalEnabled); + + // Virtualizer + final boolean isVIEnabled = prefs.getBoolean(Key.virt_enabled.toString(), + VIRTUALIZER_ENABLED_DEFAULT); + final int vIStrength = prefs.getInt(Key.virt_strength.toString(), + VIRTUALIZER_STRENGTH_DEFAULT); + editor.putBoolean(Key.virt_enabled.toString(), isVIEnabled); + editor.putInt(Key.virt_strength.toString(), vIStrength); + // BassBoost + final boolean isBBEnabled = prefs.getBoolean(Key.bb_enabled.toString(), + BASS_BOOST_ENABLED_DEFAULT); + final int bBStrength = prefs.getInt(Key.bb_strength.toString(), + BASS_BOOST_STRENGTH_DEFAULT); + editor.putBoolean(Key.bb_enabled.toString(), isBBEnabled); + editor.putInt(Key.bb_strength.toString(), bBStrength); + // Equalizer + synchronized (mEQInitLock) { + // If EQ is not initialized already create "dummy" audio session created by + // MediaPlayer and create effect on it to retrieve the invariable EQ properties + if (!mIsEQInitialized) { + final MediaPlayer mediaPlayer = new MediaPlayer(); + final int session = mediaPlayer.getAudioSessionId(); + Equalizer equalizerEffect = null; + try { + Log.d(TAG, "Creating dummy EQ effect"); + equalizerEffect = new Equalizer(PRIORITY, session); + + mEQBandLevelRange = equalizerEffect.getBandLevelRange(); + mEQNumBands = equalizerEffect.getNumberOfBands(); + mEQCenterFreq = new int[mEQNumBands]; + for (short band = 0; band < mEQNumBands; band++) { + mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band); + } + mEQNumPresets = equalizerEffect.getNumberOfPresets(); + mEQPresetNames = new String[mEQNumPresets]; + mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands]; + for (short preset = 0; preset < mEQNumPresets; preset++) { + mEQPresetNames[preset] = equalizerEffect.getPresetName(preset); + equalizerEffect.usePreset(preset); + for (short band = 0; band < mEQNumBands; band++) { + mEQPresetOpenSLESBandLevel[preset][band] = equalizerEffect + .getBandLevel(band); + } + } + + mIsEQInitialized = true; + } catch (final IllegalStateException e) { + Log.e(TAG, "Equalizer: " + e); + } catch (final IllegalArgumentException e) { + Log.e(TAG, "Equalizer: " + e); + } catch (final UnsupportedOperationException e) { + Log.e(TAG, "Equalizer: " + e); + } catch (final RuntimeException e) { + Log.e(TAG, "Equalizer: " + e); + } finally { + if (equalizerEffect != null) { + equalizerEffect.release(); + } + mediaPlayer.release(); + + // When there was a failure set some good defaults + if (!mIsEQInitialized) { + mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands]; + for (short preset = 0; preset < mEQNumPresets; preset++) { + // Init preset names to a dummy name + mEQPresetNames[preset] = prefs.getString( + Key.eq_preset_name.toString() + preset, + EQUALIZER_PRESET_NAME_DEFAULT + preset); + if (preset < EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT.length) { + mEQPresetOpenSLESBandLevel[preset] = Arrays.copyOf( + EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT[preset], + mEQNumBands); + } + } + } + } + } + editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]); + editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]); + editor.putInt(Key.eq_num_bands.toString(), mEQNumBands); + editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets); + // Resetting the EQ arrays depending on the real # bands with defaults if + // band < default size else 0 by copying default arrays over new ones + final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf( + EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands); + final short[] eQPresetUserBandLevelDefault = Arrays.copyOf( + EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands); + // If no preset prefs set use CI EXTREME (= numPresets) + final short eQPreset = (short) prefs.getInt(Key.eq_current_preset.toString(), + mEQNumPresets); + editor.putInt(Key.eq_current_preset.toString(), eQPreset); + final short[] bandLevel = new short[mEQNumBands]; + for (short band = 0; band < mEQNumBands; band++) { + if (controlMode == ControlMode.CONTROL_PREFERENCES) { + if (eQPreset < mEQNumPresets) { + // OpenSL ES effect presets + bandLevel[band] = mEQPresetOpenSLESBandLevel[eQPreset][band]; + } else if (eQPreset == mEQNumPresets) { + // CI EXTREME + bandLevel[band] = eQPresetCIExtremeBandLevel[band]; + } else { + // User + bandLevel[band] = (short) prefs.getInt( + Key.eq_preset_user_band_level.toString() + band, + eQPresetUserBandLevelDefault[band]); + } + editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]); + } + editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]); + editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band, + eQPresetCIExtremeBandLevel[band]); + editor.putInt(Key.eq_preset_user_band_level_default.toString() + band, + eQPresetUserBandLevelDefault[band]); + } + for (short preset = 0; preset < mEQNumPresets; preset++) { + editor.putString(Key.eq_preset_name.toString() + preset, mEQPresetNames[preset]); + for (short band = 0; band < mEQNumBands; band++) { + editor.putInt(Key.eq_preset_opensl_es_band_level.toString() + preset + "_" + + band, mEQPresetOpenSLESBandLevel[preset][band]); + } + } + } + final boolean isEQEnabled = prefs.getBoolean(Key.eq_enabled.toString(), + EQUALIZER_ENABLED_DEFAULT); + editor.putBoolean(Key.eq_enabled.toString(), isEQEnabled); + + // Preset reverb + final boolean isEnabledPR = prefs.getBoolean(Key.pr_enabled.toString(), + PRESET_REVERB_ENABLED_DEFAULT); + final short presetPR = (short) prefs.getInt(Key.pr_current_preset.toString(), + PRESET_REVERB_CURRENT_PRESET_DEFAULT); + editor.putBoolean(Key.pr_enabled.toString(), isEnabledPR); + editor.putInt(Key.pr_current_preset.toString(), presetPR); + + editor.commit(); + } catch (final RuntimeException e) { + Log.e(TAG, "initEffectsPreferences: processingEnabled: " + e); + } + } + + /** + * Gets the effect control mode based on the given audio session in the control panel. Control + * mode defines if the control panel is controlling effects and/or preferences + * + * @param audioSession + * System wide unique audio session identifier. + * @return effect control mode + */ + public static ControlMode getControlMode(final int audioSession) { + if (audioSession == AudioEffect.ERROR_BAD_VALUE) { + return ControlMode.CONTROL_PREFERENCES; + } + return ControlMode.CONTROL_EFFECTS; + } + + /** + * Sets boolean parameter to value for given key + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @param value + */ + public static void setParameterBoolean(final Context context, final String packageName, + final int audioSession, final Key key, final boolean value) { + try { + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + final ControlMode controlMode = getControlMode(audioSession); + boolean enabled = value; + + // Global on/off + if (key == Key.global_enabled) { + boolean processingEnabled = false; + if (value == true) { + // enable all with respect to preferences + if (controlMode == ControlMode.CONTROL_EFFECTS) { + final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession); + if (virtualizerEffect != null) { + virtualizerEffect.setEnabled(prefs.getBoolean( + Key.virt_enabled.toString(), VIRTUALIZER_ENABLED_DEFAULT)); + } + final BassBoost bassBoostEffect = getBassBoostEffect(audioSession); + if (bassBoostEffect != null) { + bassBoostEffect.setEnabled(prefs.getBoolean(Key.bb_enabled.toString(), + BASS_BOOST_ENABLED_DEFAULT)); + } + final Equalizer equalizerEffect = getEqualizerEffect(audioSession); + if (equalizerEffect != null) { + equalizerEffect.setEnabled(prefs.getBoolean(Key.eq_enabled.toString(), + EQUALIZER_ENABLED_DEFAULT)); + } + // XXX: Preset Reverb not used for the moment, so commented out the effect + // creation to not use MIPS + // final PresetReverb presetReverbEffect = + // getPresetReverbEffect(audioSession); + // if (presetReverbEffect != null) { + // presetReverbEffect.setEnabled(prefs.getBoolean( + // Key.pr_enabled.toString(), PRESET_REVERB_ENABLED_DEFAULT)); + // } + } + + processingEnabled = true; + Log.v(TAG, "processingEnabled=" + processingEnabled); + + } else { + // disable all + if (controlMode == ControlMode.CONTROL_EFFECTS) { + final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession); + if (virtualizerEffect != null) { + virtualizerEffect.setEnabled(false); + } + final BassBoost bassBoostEffect = getBassBoostEffect(audioSession); + if (bassBoostEffect != null) { + bassBoostEffect.setEnabled(false); + } + final Equalizer equalizerEffect = getEqualizerEffect(audioSession); + if (equalizerEffect != null) { + equalizerEffect.setEnabled(false); + } + // XXX: Preset Reverb not used for the moment, so commented out the effect + // creation to not use MIPS + // final PresetReverb presetReverbEffect = + // getPresetReverbEffect(audioSession); + // if (presetReverbEffect != null) { + // presetReverbEffect.setEnabled(false); + // } + } + + processingEnabled = false; + Log.v(TAG, "processingEnabled=" + processingEnabled); + } + enabled = processingEnabled; + } else if (controlMode == ControlMode.CONTROL_EFFECTS) { + final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(), + GLOBAL_ENABLED_DEFAULT); + if (isGlobalEnabled == true) { + // Set effect parameters + switch (key) { + + case global_enabled: + // Global, already handled, to get out error free + break; + + // Virtualizer + case virt_enabled: + final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession); + if (virtualizerEffect != null) { + virtualizerEffect.setEnabled(value); + enabled = virtualizerEffect.getEnabled(); + } + break; + + // BassBoost + case bb_enabled: + final BassBoost bassBoostEffect = getBassBoostEffect(audioSession); + if (bassBoostEffect != null) { + bassBoostEffect.setEnabled(value); + enabled = bassBoostEffect.getEnabled(); + } + break; + + // Equalizer + case eq_enabled: + final Equalizer equalizerEffect = getEqualizerEffect(audioSession); + if (equalizerEffect != null) { + equalizerEffect.setEnabled(value); + enabled = equalizerEffect.getEnabled(); + } + break; + + // PresetReverb + case pr_enabled: + // XXX: Preset Reverb not used for the moment, so commented out the effect + // creation to not use MIPS + // final PresetReverb presetReverbEffect = + // getPresetReverbEffect(audioSession); + // if (presetReverbEffect != null) { + // presetReverbEffect.setEnabled(value); + // enabled = presetReverbEffect.getEnabled(); + // } + break; + + default: + Log.e(TAG, "Unknown/unsupported key " + key); + return; + } + } + + } + + // Set preferences + final SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(key.toString(), enabled); + editor.commit(); + + } catch (final RuntimeException e) { + Log.e(TAG, "setParameterBoolean: " + key + "; " + value + "; " + e); + } + } + + /** + * Gets boolean parameter for given key + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @return parameter value + */ + public static Boolean getParameterBoolean(final Context context, final String packageName, + final int audioSession, final Key key) { + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + boolean value = false; + + try { + value = prefs.getBoolean(key.toString(), value); + } catch (final RuntimeException e) { + Log.e(TAG, "getParameterBoolean: " + key + "; " + value + "; " + e); + } + + return value; + + } + + /** + * Sets int parameter for given key and value arg0, arg1 + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @param arg0 + * @param arg1 + */ + public static void setParameterInt(final Context context, final String packageName, + final int audioSession, final Key key, final int arg0, final int arg1) { + String strKey = key.toString(); + int value = arg0; + + try { + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + final SharedPreferences.Editor editor = prefs.edit(); + final ControlMode controlMode = getControlMode(audioSession); + + // Set effect parameters + if (controlMode == ControlMode.CONTROL_EFFECTS) { + + switch (key) { + + // Virtualizer + case virt_strength: { + final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession); + if (virtualizerEffect != null) { + virtualizerEffect.setStrength((short) value); + value = virtualizerEffect.getRoundedStrength(); + } + break; + } + // BassBoost + case bb_strength: { + final BassBoost bassBoostEffect = getBassBoostEffect(audioSession); + if (bassBoostEffect != null) { + bassBoostEffect.setStrength((short) value); + value = bassBoostEffect.getRoundedStrength(); + } + break; + } + // Equalizer + case eq_band_level: { + if (arg1 == DUMMY_ARGUMENT) { + throw new IllegalArgumentException("Dummy arg passed."); + } + final short band = (short) arg1; + strKey = strKey + band; + final Equalizer equalizerEffect = getEqualizerEffect(audioSession); + if (equalizerEffect != null) { + equalizerEffect.setBandLevel(band, (short) value); + value = equalizerEffect.getBandLevel(band); + // save band level in User preset + editor.putInt(Key.eq_preset_user_band_level.toString() + band, value); + } + break; + } + case eq_current_preset: { + final Equalizer equalizerEffect = getEqualizerEffect(audioSession); + if (equalizerEffect != null) { + final short preset = (short) value; + final int numBands = prefs.getInt(Key.eq_num_bands.toString(), + EQUALIZER_NUMBER_BANDS_DEFAULT); + final int numPresets = prefs.getInt(Key.eq_num_presets.toString(), + EQUALIZER_NUMBER_PRESETS_DEFAULT); + + if (preset < numPresets) { + // OpenSL ES EQ Effect presets + equalizerEffect.usePreset(preset); + value = equalizerEffect.getCurrentPreset(); + } else { + final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf( + EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands); + final short[] eQPresetUserBandLevelDefault = Arrays.copyOf( + EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands); + // Set the band levels manually for custom presets + for (short band = 0; band < numBands; band++) { + short bandLevel = 0; + if (preset == numPresets) { + // CI EXTREME + bandLevel = (short) prefs.getInt( + Key.eq_preset_ci_extreme_band_level.toString() + band, + eQPresetCIExtremeBandLevelDefault[band]); + } else { + // User + bandLevel = (short) prefs.getInt( + Key.eq_preset_user_band_level.toString() + band, + eQPresetUserBandLevelDefault[band]); + } + equalizerEffect.setBandLevel(band, bandLevel); + } + } + + // update band levels + for (short band = 0; band < numBands; band++) { + final short level = equalizerEffect.getBandLevel(band); + editor.putInt(Key.eq_band_level.toString() + band, level); + } + } + break; + } + case eq_preset_user_band_level: + // Fall through + case eq_preset_user_band_level_default: + // Fall through + case eq_preset_ci_extreme_band_level: { + if (arg1 == DUMMY_ARGUMENT) { + throw new IllegalArgumentException("Dummy arg passed."); + } + final short band = (short) arg1; + strKey = strKey + band; + break; + } + case pr_current_preset: + // XXX: Preset Reverb not used for the moment, so commented out the effect + // creation to not use MIPS + // final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession); + // if (presetReverbEffect != null) { + // presetReverbEffect.setPreset((short) value); + // value = presetReverbEffect.getPreset(); + // } + break; + default: + Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key); + return; + } + } else { + switch (key) { + // Virtualizer + case virt_strength: + // Do nothing + break; + case virt_type: + // Do nothing + break; + + // BassBoost + case bb_strength: + // Do nothing + break; + + // Equalizer + case eq_band_level: { + if (arg1 == DUMMY_ARGUMENT) { + throw new IllegalArgumentException("Dummy arg passed."); + } + final short band = (short) arg1; + strKey = strKey + band; + + editor.putInt(Key.eq_preset_user_band_level.toString() + band, value); + break; + } + case eq_current_preset: { + final short preset = (short) value; + final int numBands = prefs.getInt(Key.eq_num_bands.toString(), + EQUALIZER_NUMBER_BANDS_DEFAULT); + final int numPresets = prefs.getInt(Key.eq_num_presets.toString(), + EQUALIZER_NUMBER_PRESETS_DEFAULT); + + final short[][] eQPresetOpenSLESBandLevelDefault = Arrays.copyOf( + EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT, numBands); + final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf( + EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands); + final short[] eQPresetUserBandLevelDefault = Arrays.copyOf( + EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands); + for (short band = 0; band < numBands; band++) { + short bandLevel = 0; + if (preset < numPresets) { + // OpenSL ES EQ Effect presets + bandLevel = (short) prefs.getInt( + Key.eq_preset_opensl_es_band_level.toString() + preset + "_" + + band, eQPresetOpenSLESBandLevelDefault[preset][band]); + } else if (preset == numPresets) { + // CI EXTREME + bandLevel = (short) prefs.getInt( + Key.eq_preset_ci_extreme_band_level.toString() + band, + eQPresetCIExtremeBandLevelDefault[band]); + } else { + // User + bandLevel = (short) prefs.getInt( + Key.eq_preset_user_band_level.toString() + band, + eQPresetUserBandLevelDefault[band]); + } + editor.putInt(Key.eq_band_level.toString() + band, bandLevel); + } + break; + } + case eq_preset_user_band_level: + // Fall through + case eq_preset_user_band_level_default: + // Fall through + case eq_preset_ci_extreme_band_level: { + if (arg1 == DUMMY_ARGUMENT) { + throw new IllegalArgumentException("Dummy arg passed."); + } + final short band = (short) arg1; + strKey = strKey + band; + break; + } + case pr_current_preset: + // Do nothing + break; + default: + Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key); + return; + } + } + + // Set preferences + editor.putInt(strKey, value); + editor.commit(); + + } catch (final RuntimeException e) { + Log.e(TAG, "setParameterInt: " + key + "; " + arg0 + "; " + arg1 + "; " + e); + } + + } + + /** + * Sets int parameter for given key and value arg + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @param arg + */ + public static void setParameterInt(final Context context, final String packageName, + final int audioSession, final Key key, final int arg) { + setParameterInt(context, packageName, audioSession, key, arg, DUMMY_ARGUMENT); + } + + /** + * Gets int parameter given key + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @return parameter value + */ + public static int getParameterInt(final Context context, final String packageName, + final int audioSession, final String key) { + int value = 0; + + try { + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + value = prefs.getInt(key, value); + } catch (final RuntimeException e) { + Log.e(TAG, "getParameterInt: " + key + "; " + e); + } + + return value; + } + + /** + * Gets int parameter given key + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @return parameter value + */ + public static int getParameterInt(final Context context, final String packageName, + final int audioSession, final Key key) { + return getParameterInt(context, packageName, audioSession, key.toString()); + } + + /** + * Gets int parameter given key and arg + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param audioSession + * @param key + * @param arg + * @return parameter value + */ + public static int getParameterInt(final Context context, final String packageName, + final int audioSession, final Key key, final int arg) { + return getParameterInt(context, packageName, audioSession, key.toString() + arg); + } + + /** + * Gets int parameter given key, arg0 and arg1 + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param audioSession + * @param key + * @param arg0 + * @param arg1 + * @return parameter value + */ + public static int getParameterInt(final Context context, final String packageName, + final int audioSession, final Key key, final int arg0, final int arg1) { + return getParameterInt(context, packageName, audioSession, key.toString() + arg0 + "_" + + arg1); + } + + /** + * Gets integer array parameter given key. Returns null if not found. + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @return parameter value array + */ + public static int[] getParameterIntArray(final Context context, final String packageName, + final int audioSession, final Key key) { + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + + int[] intArray = null; + try { + // Get effect parameters + switch (key) { + case eq_level_range: { + intArray = new int[2]; + break; + } + case eq_center_freq: + // Fall through + case eq_band_level: + // Fall through + case eq_preset_user_band_level: + // Fall through + case eq_preset_user_band_level_default: + // Fall through + case eq_preset_ci_extreme_band_level: { + final int numBands = prefs.getInt(Key.eq_num_bands.toString(), 0); + intArray = new int[numBands]; + break; + } + default: + Log.e(TAG, "getParameterIntArray: Unknown/unsupported key " + key); + return null; + } + + for (int i = 0; i < intArray.length; i++) { + intArray[i] = prefs.getInt(key.toString() + i, 0); + } + + } catch (final RuntimeException e) { + Log.e(TAG, "getParameterIntArray: " + key + "; " + e); + } + + return intArray; + } + + /** + * Gets string parameter given key. Returns empty string if not found. + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @return parameter value + */ + public static String getParameterString(final Context context, final String packageName, + final int audioSession, final String key) { + String value = ""; + try { + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + + // Get effect parameters + value = prefs.getString(key, value); + + } catch (final RuntimeException e) { + Log.e(TAG, "getParameterString: " + key + "; " + e); + } + + return value; + } + + /** + * Gets string parameter given key. + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param key + * @return parameter value + */ + public static String getParameterString(final Context context, final String packageName, + final int audioSession, final Key key) { + return getParameterString(context, packageName, audioSession, key.toString()); + } + + /** + * Gets string parameter given key and arg. + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param args + * @return parameter value + */ + public static String getParameterString(final Context context, final String packageName, + final int audioSession, final Key key, final int arg) { + return getParameterString(context, packageName, audioSession, key.toString() + arg); + } + + /** + * Opens/initializes the effects session for the given audio session with preferences linked to + * the given package name and context. + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + */ + public static void openSession(final Context context, final String packageName, + final int audioSession) { + Log.v(TAG, "openSession(" + context + ", " + packageName + ", " + audioSession + ")"); + final String methodTag = "openSession: "; + + // init preferences + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + final SharedPreferences.Editor editor = prefs.edit(); + + final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(), + GLOBAL_ENABLED_DEFAULT); + editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled); + + // Manage audioSession information + + // Retrieve AudioSession Id from map + boolean isExistingAudioSession = false; + + try { + final Integer currentAudioSession = mPackageSessions.putIfAbsent(packageName, + audioSession); + if (currentAudioSession != null) { + // Compare with passed argument + if (currentAudioSession == audioSession) { + // FIXME: Normally, we should exit the function here + // BUT: we have to take care of the virtualizer because of + // a bug in the Android Effects Framework + // editor.commit(); + // return; + isExistingAudioSession = true; + } else { + closeSession(context, packageName, currentAudioSession); + } + } + } catch (final NullPointerException e) { + Log.e(TAG, methodTag + e); + editor.commit(); + return; + } + + // Because the audioSession is new, get effects & settings from shared preferences + + // Virtualizer + // create effect + final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession); + { + final String errorTag = methodTag + "Virtualizer error: "; + + try { + // read parameters + final boolean isEnabled = prefs.getBoolean(Key.virt_enabled.toString(), + VIRTUALIZER_ENABLED_DEFAULT); + final int strength = prefs.getInt(Key.virt_strength.toString(), + VIRTUALIZER_STRENGTH_DEFAULT); + // init settings + Virtualizer.Settings settings = new Virtualizer.Settings("Virtualizer;strength=" + + strength); + + virtualizerEffect.setProperties(settings); + + // set parameters + if (isGlobalEnabled == true) { + virtualizerEffect.setEnabled(isEnabled); + } else { + virtualizerEffect.setEnabled(false); + } + + // get parameters + settings = virtualizerEffect.getProperties(); + Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled); + + // update preferences + editor.putBoolean(Key.virt_enabled.toString(), isEnabled); + editor.putInt(Key.virt_strength.toString(), settings.strength); + } catch (final RuntimeException e) { + Log.e(TAG, errorTag + e); + } + } + + // In case of an existing audio session + // Exit after the virtualizer has been re-enabled + + if (isExistingAudioSession) { + editor.commit(); + return; + } + + // BassBoost + // create effect + final BassBoost bassBoostEffect = getBassBoostEffect(audioSession); + { + final String errorTag = methodTag + "BassBoost error: "; + + try { + // read parameters + final boolean isEnabled = prefs.getBoolean(Key.bb_enabled.toString(), + BASS_BOOST_ENABLED_DEFAULT); + final int strength = prefs.getInt(Key.bb_strength.toString(), + BASS_BOOST_STRENGTH_DEFAULT); + + // init settings + BassBoost.Settings settings = new BassBoost.Settings("BassBoost;strength=" + + strength); + + bassBoostEffect.setProperties(settings); + + // set parameters + if (isGlobalEnabled == true) { + bassBoostEffect.setEnabled(isEnabled); + } else { + bassBoostEffect.setEnabled(false); + } + + // get parameters + settings = bassBoostEffect.getProperties(); + Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled); + + // update preferences + editor.putBoolean(Key.bb_enabled.toString(), isEnabled); + editor.putInt(Key.bb_strength.toString(), settings.strength); + } catch (final RuntimeException e) { + Log.e(TAG, errorTag + e); + } + } + + // Equalizer + // create effect + final Equalizer equalizerEffect = getEqualizerEffect(audioSession); + { + final String errorTag = methodTag + "Equalizer error: "; + + try { + final short eQNumBands; + final short[] bandLevel; + final int[] eQCenterFreq; + final short eQNumPresets; + final String[] eQPresetNames; + short eQPreset; + synchronized (mEQInitLock) { + // read parameters + mEQBandLevelRange = equalizerEffect.getBandLevelRange(); + mEQNumBands = equalizerEffect.getNumberOfBands(); + mEQCenterFreq = new int[mEQNumBands]; + mEQNumPresets = equalizerEffect.getNumberOfPresets(); + mEQPresetNames = new String[mEQNumPresets]; + + for (short preset = 0; preset < mEQNumPresets; preset++) { + mEQPresetNames[preset] = equalizerEffect.getPresetName(preset); + editor.putString(Key.eq_preset_name.toString() + preset, + mEQPresetNames[preset]); + } + + editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]); + editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]); + editor.putInt(Key.eq_num_bands.toString(), mEQNumBands); + editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets); + // Resetting the EQ arrays depending on the real # bands with defaults if band < + // default size else 0 by copying default arrays over new ones + final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf( + EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands); + final short[] eQPresetUserBandLevelDefault = Arrays.copyOf( + EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands); + // If no preset prefs set use CI EXTREME (= numPresets) + eQPreset = (short) prefs + .getInt(Key.eq_current_preset.toString(), mEQNumPresets); + if (eQPreset < mEQNumPresets) { + // OpenSL ES effect presets + equalizerEffect.usePreset(eQPreset); + eQPreset = equalizerEffect.getCurrentPreset(); + } else { + for (short band = 0; band < mEQNumBands; band++) { + short level = 0; + if (eQPreset == mEQNumPresets) { + // CI EXTREME + level = eQPresetCIExtremeBandLevel[band]; + } else { + // User + level = (short) prefs.getInt( + Key.eq_preset_user_band_level.toString() + band, + eQPresetUserBandLevelDefault[band]); + } + equalizerEffect.setBandLevel(band, level); + } + } + editor.putInt(Key.eq_current_preset.toString(), eQPreset); + + bandLevel = new short[mEQNumBands]; + for (short band = 0; band < mEQNumBands; band++) { + mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band); + bandLevel[band] = equalizerEffect.getBandLevel(band); + + editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]); + editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]); + editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band, + eQPresetCIExtremeBandLevel[band]); + editor.putInt(Key.eq_preset_user_band_level_default.toString() + band, + eQPresetUserBandLevelDefault[band]); + } + + eQNumBands = mEQNumBands; + eQCenterFreq = mEQCenterFreq; + eQNumPresets = mEQNumPresets; + eQPresetNames = mEQPresetNames; + } + + final boolean isEnabled = prefs.getBoolean(Key.eq_enabled.toString(), + EQUALIZER_ENABLED_DEFAULT); + editor.putBoolean(Key.eq_enabled.toString(), isEnabled); + if (isGlobalEnabled == true) { + equalizerEffect.setEnabled(isEnabled); + } else { + equalizerEffect.setEnabled(false); + } + + // dump + Log.v(TAG, "Parameters: Equalizer"); + Log.v(TAG, "bands=" + eQNumBands); + String str = "levels="; + for (short band = 0; band < eQNumBands; band++) { + str = str + bandLevel[band] + "; "; + } + Log.v(TAG, str); + str = "center="; + for (short band = 0; band < eQNumBands; band++) { + str = str + eQCenterFreq[band] + "; "; + } + Log.v(TAG, str); + str = "presets="; + for (short preset = 0; preset < eQNumPresets; preset++) { + str = str + eQPresetNames[preset] + "; "; + } + Log.v(TAG, str); + Log.v(TAG, "current=" + eQPreset); + } catch (final RuntimeException e) { + Log.e(TAG, errorTag + e); + } + } + + // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not + // use MIPS left in the code for (future) reference. + // Preset reverb + // create effect + // final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession); + // { + // final String errorTag = methodTag + "PresetReverb error: "; + // + // try { + // // read parameters + // final boolean isEnabled = prefs.getBoolean(Key.pr_enabled.toString(), + // PRESET_REVERB_ENABLED_DEFAULT); + // final short preset = (short) prefs.getInt(Key.pr_current_preset.toString(), + // PRESET_REVERB_CURRENT_PRESET_DEFAULT); + // + // // init settings + // PresetReverb.Settings settings = new PresetReverb.Settings("PresetReverb;preset=" + // + preset); + // + // // read/update preferences + // presetReverbEffect.setProperties(settings); + // + // // set parameters + // if (isGlobalEnabled == true) { + // presetReverbEffect.setEnabled(isEnabled); + // } else { + // presetReverbEffect.setEnabled(false); + // } + // + // // get parameters + // settings = presetReverbEffect.getProperties(); + // Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled); + // + // // update preferences + // editor.putBoolean(Key.pr_enabled.toString(), isEnabled); + // editor.putInt(Key.pr_current_preset.toString(), settings.preset); + // } catch (final RuntimeException e) { + // Log.e(TAG, errorTag + e); + // } + // } + editor.commit(); + } + + /** + * Closes the audio session (release effects) for the given session + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + */ + public static void closeSession(final Context context, final String packageName, + final int audioSession) { + Log.v(TAG, "closeSession(" + context + ", " + packageName + ", " + audioSession + ")"); + + // PresetReverb + final PresetReverb presetReverb = mPresetReverbInstances.remove(audioSession); + if (presetReverb != null) { + presetReverb.release(); + } + // Equalizer + final Equalizer equalizer = mEQInstances.remove(audioSession); + if (equalizer != null) { + equalizer.release(); + } + // BassBoost + final BassBoost bassBoost = mBassBoostInstances.remove(audioSession); + if (bassBoost != null) { + bassBoost.release(); + } + // Virtualizer + final Virtualizer virtualizer = mVirtualizerInstances.remove(audioSession); + if (virtualizer != null) { + virtualizer.release(); + } + + mPackageSessions.remove(packageName); + } + + /** + * Enables or disables all effects (global enable/disable) for a given context, package name and + * audio session. It sets/inits the control mode and preferences and then sets the global + * enabled parameter. + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + * @param enabled + */ + public static void setEnabledAll(final Context context, final String packageName, + final int audioSession, final boolean enabled) { + initEffectsPreferences(context, packageName, audioSession); + setParameterBoolean(context, packageName, audioSession, Key.global_enabled, enabled); + } + + /** + * Sets the defaults for all effects. + * + * @param context + * @param packageName + * @param audioSession + * System wide unique audio session identifier. + */ + public static void setEffectDefaults(final Context context, final String packageName, + final int audioSession) { + final SharedPreferences prefs = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE); + final SharedPreferences.Editor editor = prefs.edit(); + + setParameterBoolean(context, packageName, audioSession, Key.global_enabled, + GLOBAL_ENABLED_DEFAULT); + setParameterBoolean(context, packageName, audioSession, Key.virt_enabled, + VIRTUALIZER_ENABLED_DEFAULT); + setParameterInt(context, packageName, audioSession, Key.virt_strength, + VIRTUALIZER_STRENGTH_DEFAULT); + setParameterBoolean(context, packageName, audioSession, Key.bb_enabled, + BASS_BOOST_ENABLED_DEFAULT); + setParameterInt(context, packageName, audioSession, Key.bb_strength, + BASS_BOOST_STRENGTH_DEFAULT); + setParameterBoolean(context, packageName, audioSession, Key.eq_enabled, + EQUALIZER_ENABLED_DEFAULT); + // CI preset idx = numPresets + final int numPresets = prefs.getInt(Key.eq_num_presets.toString(), EQUALIZER_NUMBER_PRESETS_DEFAULT); + setParameterInt(context, packageName, audioSession, Key.eq_current_preset, numPresets); + // Reset User EQ levels + final int numBands = prefs.getInt(Key.eq_num_bands.toString(), EQUALIZER_NUMBER_BANDS_DEFAULT); + final short[] eQPresetUserBandLevelDefault = Arrays.copyOf( + EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands); + for (short band = 0; band < numBands; band++) { + editor.putInt(Key.eq_preset_user_band_level.toString() + band, + eQPresetUserBandLevelDefault[band]); + } + setParameterBoolean(context, packageName, numBands, Key.pr_enabled, + PRESET_REVERB_ENABLED_DEFAULT); + setParameterInt(context, packageName, numBands, Key.pr_current_preset, + PRESET_REVERB_CURRENT_PRESET_DEFAULT); + editor.commit(); + } + + /** + * Gets the virtualizer effect for the given audio session. If the effect on the session doesn't + * exist yet, create it and add to collection. + * + * @param audioSession + * System wide unique audio session identifier. + * @return virtualizerEffect + */ + private static Virtualizer getVirtualizerEffect(final int audioSession) { + Virtualizer virtualizerEffect = mVirtualizerInstances.get(audioSession); + if (virtualizerEffect == null) { + try { + final Virtualizer newVirtualizerEffect = new Virtualizer(PRIORITY, audioSession); + virtualizerEffect = mVirtualizerInstances.putIfAbsent(audioSession, + newVirtualizerEffect); + if (virtualizerEffect == null) { + // put succeeded, use new value + virtualizerEffect = newVirtualizerEffect; + } + } catch (final IllegalArgumentException e) { + Log.e(TAG, "Virtualizer: " + e); + } catch (final UnsupportedOperationException e) { + Log.e(TAG, "Virtualizer: " + e); + } catch (final RuntimeException e) { + Log.e(TAG, "Virtualizer: " + e); + } + } + return virtualizerEffect; + } + + /** + * Gets the bass boost effect for the given audio session. If the effect on the session doesn't + * exist yet, create it and add to collection. + * + * @param audioSession + * System wide unique audio session identifier. + * @return bassBoostEffect + */ + private static BassBoost getBassBoostEffect(final int audioSession) { + BassBoost bassBoostEffect = mBassBoostInstances.get(audioSession); + if (bassBoostEffect == null) { + try { + final BassBoost newBassBoostEffect = new BassBoost(PRIORITY, audioSession); + bassBoostEffect = mBassBoostInstances.putIfAbsent(audioSession, newBassBoostEffect); + if (bassBoostEffect == null) { + // put succeeded, use new value + bassBoostEffect = newBassBoostEffect; + } + } catch (final IllegalArgumentException e) { + Log.e(TAG, "BassBoost: " + e); + } catch (final UnsupportedOperationException e) { + Log.e(TAG, "BassBoost: " + e); + } catch (final RuntimeException e) { + Log.e(TAG, "BassBoost: " + e); + } + } + return bassBoostEffect; + } + + /** + * Gets the equalizer effect for the given audio session. If the effect on the session doesn't + * exist yet, create it and add to collection. + * + * @param audioSession + * System wide unique audio session identifier. + * @return equalizerEffect + */ + private static Equalizer getEqualizerEffect(final int audioSession) { + Equalizer equalizerEffect = mEQInstances.get(audioSession); + if (equalizerEffect == null) { + try { + final Equalizer newEqualizerEffect = new Equalizer(PRIORITY, audioSession); + equalizerEffect = mEQInstances.putIfAbsent(audioSession, newEqualizerEffect); + if (equalizerEffect == null) { + // put succeeded, use new value + equalizerEffect = newEqualizerEffect; + } + } catch (final IllegalArgumentException e) { + Log.e(TAG, "Equalizer: " + e); + } catch (final UnsupportedOperationException e) { + Log.e(TAG, "Equalizer: " + e); + } catch (final RuntimeException e) { + Log.e(TAG, "Equalizer: " + e); + } + } + return equalizerEffect; + } + + // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not + // use MIPS + // /** + // * Gets the preset reverb effect for the given audio session. If the effect on the session + // * doesn't exist yet, create it and add to collection. + // * + // * @param audioSession + // * System wide unique audio session identifier. + // * @return presetReverbEffect + // */ + // private static PresetReverb getPresetReverbEffect(final int audioSession) { + // PresetReverb presetReverbEffect = mPresetReverbInstances.get(audioSession); + // if (presetReverbEffect == null) { + // try { + // final PresetReverb newPresetReverbEffect = new PresetReverb(PRIORITY, audioSession); + // presetReverbEffect = mPresetReverbInstances.putIfAbsent(audioSession, + // newPresetReverbEffect); + // if (presetReverbEffect == null) { + // // put succeeded, use new value + // presetReverbEffect = newPresetReverbEffect; + // } + // } catch (final IllegalArgumentException e) { + // Log.e(TAG, "PresetReverb: " + e); + // } catch (final UnsupportedOperationException e) { + // Log.e(TAG, "PresetReverb: " + e); + // } catch (final RuntimeException e) { + // Log.e(TAG, "PresetReverb: " + e); + // } + // } + // return presetReverbEffect; + // } +} diff --git a/src/com/android/musicfx/ControlPanelReceiver.java b/src/com/android/musicfx/ControlPanelReceiver.java index 7e41557..563e3ef 100644 --- a/src/com/android/musicfx/ControlPanelReceiver.java +++ b/src/com/android/musicfx/ControlPanelReceiver.java @@ -1,105 +1,105 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.musicfx;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.util.HashMap;
-
-public class ControlPanelReceiver extends BroadcastReceiver {
-
- private final static String TAG = "MusicFXControlPanelReceiver";
-
- @Override
- public void onReceive(final Context context, final Intent intent) {
-
- Log.v(TAG, "onReceive");
-
- if ((context == null) || (intent == null)) {
- Log.w(TAG, "Context or intent is null. Do nothing.");
- return;
- }
-
- final String action = intent.getAction();
- final String packageName = intent.getStringExtra(AudioEffect.EXTRA_PACKAGE_NAME);
- final int audioSession = intent.getIntExtra(AudioEffect.EXTRA_AUDIO_SESSION,
- AudioEffect.ERROR_BAD_VALUE);
-
- Log.v(TAG, "Action: " + action);
- Log.v(TAG, "Package name: " + packageName);
- Log.v(TAG, "Audio session: " + audioSession);
-
- // check package name
- if (packageName == null) {
- Log.w(TAG, "Null package name");
- return;
- }
-
- // check audio session
- if ((audioSession == AudioEffect.ERROR_BAD_VALUE) || (audioSession < 0)) {
- Log.w(TAG, "Invalid or missing audio session " + audioSession);
- return;
- }
-
- // open audio session
- if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION)) {
-
- // retrieve the effect enabled state
- final boolean isGlobalEnabled = context.getSharedPreferences(packageName,
- Context.MODE_PRIVATE).getBoolean(
- ControlPanelEffect.Key.global_enabled.toString(),
- ControlPanelEffect.GLOBAL_ENABLED_DEFAULT);
-
- ControlPanelEffect.openSession(context, packageName, audioSession);
- }
-
- // close audio session
- if (action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
-
- ControlPanelEffect.closeSession(context, packageName, audioSession);
- }
-
- // set params
- if (action.equals("AudioEffect.ACTION_SET_PARAM")) {
- final String param = intent.getStringExtra("AudioEffect.EXTRA_PARAM");
-
- if (param.equals("GLOBAL_ENABLED")) {
- final Boolean value = intent.getBooleanExtra("AudioEffect.EXTRA_VALUE", false);
- ControlPanelEffect.setParameterBoolean(context, packageName, audioSession,
- ControlPanelEffect.Key.global_enabled, value);
- }
- }
-
- // get params
- if (action.equals("AudioEffect.ACTION_GET_PARAM")) {
- final String param = intent.getStringExtra("AudioEffect.EXTRA_PARAM");
-
- if (param.equals("GLOBAL_ENABLED")) {
- final Boolean value = ControlPanelEffect.getParameterBoolean(context, packageName,
- audioSession, ControlPanelEffect.Key.global_enabled);
- final Bundle extras = new Bundle();
- extras.putBoolean("GLOBAL_ENABLED", value);
- setResultExtras(extras);
- }
- }
- }
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.musicfx; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.media.audiofx.AudioEffect; +import android.os.Bundle; +import android.util.Log; + +import java.util.HashMap; + +public class ControlPanelReceiver extends BroadcastReceiver { + + private final static String TAG = "MusicFXControlPanelReceiver"; + + @Override + public void onReceive(final Context context, final Intent intent) { + + Log.v(TAG, "onReceive"); + + if ((context == null) || (intent == null)) { + Log.w(TAG, "Context or intent is null. Do nothing."); + return; + } + + final String action = intent.getAction(); + final String packageName = intent.getStringExtra(AudioEffect.EXTRA_PACKAGE_NAME); + final int audioSession = intent.getIntExtra(AudioEffect.EXTRA_AUDIO_SESSION, + AudioEffect.ERROR_BAD_VALUE); + + Log.v(TAG, "Action: " + action); + Log.v(TAG, "Package name: " + packageName); + Log.v(TAG, "Audio session: " + audioSession); + + // check package name + if (packageName == null) { + Log.w(TAG, "Null package name"); + return; + } + + // check audio session + if ((audioSession == AudioEffect.ERROR_BAD_VALUE) || (audioSession < 0)) { + Log.w(TAG, "Invalid or missing audio session " + audioSession); + return; + } + + // open audio session + if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION)) { + + // retrieve the effect enabled state + final boolean isGlobalEnabled = context.getSharedPreferences(packageName, + Context.MODE_PRIVATE).getBoolean( + ControlPanelEffect.Key.global_enabled.toString(), + ControlPanelEffect.GLOBAL_ENABLED_DEFAULT); + + ControlPanelEffect.openSession(context, packageName, audioSession); + } + + // close audio session + if (action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { + + ControlPanelEffect.closeSession(context, packageName, audioSession); + } + + // set params + if (action.equals("AudioEffect.ACTION_SET_PARAM")) { + final String param = intent.getStringExtra("AudioEffect.EXTRA_PARAM"); + + if (param.equals("GLOBAL_ENABLED")) { + final Boolean value = intent.getBooleanExtra("AudioEffect.EXTRA_VALUE", false); + ControlPanelEffect.setParameterBoolean(context, packageName, audioSession, + ControlPanelEffect.Key.global_enabled, value); + } + } + + // get params + if (action.equals("AudioEffect.ACTION_GET_PARAM")) { + final String param = intent.getStringExtra("AudioEffect.EXTRA_PARAM"); + + if (param.equals("GLOBAL_ENABLED")) { + final Boolean value = ControlPanelEffect.getParameterBoolean(context, packageName, + audioSession, ControlPanelEffect.Key.global_enabled); + final Bundle extras = new Bundle(); + extras.putBoolean("GLOBAL_ENABLED", value); + setResultExtras(extras); + } + } + } +} diff --git a/src/com/android/musicfx/FirstUseReceiver.java b/src/com/android/musicfx/FirstUseReceiver.java index f055261..823d92a 100644 --- a/src/com/android/musicfx/FirstUseReceiver.java +++ b/src/com/android/musicfx/FirstUseReceiver.java @@ -1,47 +1,47 @@ -/*
- * Copyright (C) 2010-2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.musicfx;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.media.audiofx.AudioEffect;
-import android.util.Log;
-
-/**
- *
- */
-public class FirstUseReceiver extends BroadcastReceiver {
-
- private final static String TAG = "MusicFXFirstUseReceiver";
-
- @Override
- public void onReceive(final Context context, final Intent intent) {
-
- if ((context == null) || (intent == null)) {
- Log.w(TAG, "Context or intent is null. Do nothing.");
- return;
- }
-
- final String action = intent.getAction();
-
- if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION)) {
- final String packageName = intent.getStringExtra(AudioEffect.EXTRA_PACKAGE_NAME);
- ActivityFirstUse.checkFirstUse(context, packageName);
- }
- }
-}
+/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.musicfx; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.media.audiofx.AudioEffect; +import android.util.Log; + +/** + * + */ +public class FirstUseReceiver extends BroadcastReceiver { + + private final static String TAG = "MusicFXFirstUseReceiver"; + + @Override + public void onReceive(final Context context, final Intent intent) { + + if ((context == null) || (intent == null)) { + Log.w(TAG, "Context or intent is null. Do nothing."); + return; + } + + final String action = intent.getAction(); + + if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION)) { + final String packageName = intent.getStringExtra(AudioEffect.EXTRA_PACKAGE_NAME); + ActivityFirstUse.checkFirstUse(context, packageName); + } + } +} |
