Python Libraries Used in Research


An introduction into key libraries and their usage in Python.

  • Learn about Python scope rules.
  • Learn the basics of scientific and vectorized computing using numpy.
  • Learn the basics of plotting with matplotlib.pyplot.
  • Learn the basics of random numbers with the random module
  • Learn how to measure time.
In [2]:
def increment(n):
    n += 1
    return n

n = 1
while n < 10:
    n = increment(n)
print(n)
10
In [3]:
ml = [12,33,55,77,99,31]
ml.sort()
print(ml)
ml.reverse()
print(ml)
[12, 31, 33, 55, 77, 99]
[99, 77, 55, 33, 31, 12]
In [4]:
ml.remove(77)
In [5]:
ml
Out[5]:
[99, 55, 33, 31, 12]
In [6]:
ml.append(11)
ml.append(3)
ml.append(4)
ml.append(3)
In [7]:
ml
Out[7]:
[99, 55, 33, 31, 12, 11, 3, 4, 3]
In [8]:
ml.remove(3)
In [9]:
print(ml)
[99, 55, 33, 31, 12, 11, 4, 3]
In [10]:
class MyList(list):
    def remove_min(self) :
        self.remove(min(self))
    
    def remove_max(self) :
        self.remove(max(self))                  
        
In [11]:
x = [1,7,8,9,33,11]
y = MyList(x)
dir(x)
dir(y)
Out[11]:
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__hash__',
 '__iadd__',
 '__imul__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__module__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__reversed__',
 '__rmul__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'remove_max',
 'remove_min',
 'reverse',
 'sort']
In [12]:
y
Out[12]:
[1, 7, 8, 9, 33, 11]
In [13]:
y.remove_max()
In [14]:
y
Out[14]:
[1, 7, 8, 9, 11]
In [15]:
y.remove_min()
In [16]:
y
Out[16]:
[7, 8, 9, 11]
In [17]:
y.append('suraj')
In [18]:
y
Out[18]:
[7, 8, 9, 11, 'suraj']

Introduction to NumPy Arrays

In [19]:
import numpy as np
In [20]:
zero_vector = np.zeros(5)
In [21]:
zero_vector
Out[21]:
array([0., 0., 0., 0., 0.])
In [22]:
zero_matrix = np.zeros((5,6))
In [23]:
zero_matrix
Out[23]:
array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]])
In [24]:
type(zero_vector)
Out[24]:
numpy.ndarray
In [25]:
type(zero_matrix)
Out[25]:
numpy.ndarray
In [26]:
ones_matrix = np.ones((5,6))
In [27]:
ones_matrix
Out[27]:
array([[1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.]])
In [28]:
empty_matrix = np.empty((5,3))
In [29]:
empty_matrix
Out[29]:
array([[6.90458792e-310, 4.66597892e-310, 0.00000000e+000],
       [0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
       [0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
       [0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
       [0.00000000e+000, 0.00000000e+000, 6.32404027e-322]])
In [30]:
x = np.array([1,3,5,6,7,8,])
In [31]:
x
Out[31]:
array([1, 3, 5, 6, 7, 8])
In [32]:
Y = np.array([[1,2,3],[4,5,6]])
In [33]:
Y
Out[33]:
array([[1, 2, 3],
       [4, 5, 6]])
In [34]:
Y.transpose()
Out[34]:
array([[1, 4],
       [2, 5],
       [3, 6]])
In [35]:
Y
Out[35]:
array([[1, 2, 3],
       [4, 5, 6]])
In [36]:
x = np.array([[3,6],[5,7]])
y = x.transpose()
print(y)
[[3 5]
 [6 7]]
In [37]:
x[1,:]
Out[37]:
array([5, 7])
In [38]:
y[1,:]
Out[38]:
array([6, 7])
In [39]:
y[:,0]
Out[39]:
array([3, 6])
In [40]:
y[1]
Out[40]:
array([6, 7])
In [41]:
y1 = [4,5,5,6,7,8,9,0]
In [42]:
y1[:5]
Out[42]:
[4, 5, 5, 6, 7]
In [43]:
np.array([4,5,6,7]) + np.array([1,3,6,7]) + y1[:4]
Out[43]:
array([ 9, 13, 17, 20])
In [44]:
x = np.array([1,2,5])
x[1:2]
Out[44]:
array([2])
In [45]:
z1 = np.array([1,3,5,79])
z2 = z1 + 1
In [46]:
z2
Out[46]:
array([ 2,  4,  6, 80])
In [47]:
ind = [0,2,3]
z1[ind]
Out[47]:
array([ 1,  5, 79])
In [48]:
z2 > 6
Out[48]:
array([False, False, False,  True])
In [49]:
z2[z2 > 6]
Out[49]:
array([80])
In [50]:
z1[z2>6]
Out[50]:
array([79])
In [51]:
np.linspace(0,100,10)
Out[51]:
array([  0.        ,  11.11111111,  22.22222222,  33.33333333,
        44.44444444,  55.55555556,  66.66666667,  77.77777778,
        88.88888889, 100.        ])
In [52]:
np.logspace(np.log10(250),np.log10(500), 10)
Out[52]:
array([250.        , 270.01493472, 291.63225989, 314.98026247,
       340.19750004, 367.43362307, 396.85026299, 428.62199143,
       462.93735614, 500.        ])
In [53]:
z1.shape
Out[53]:
(4,)
In [54]:
z2.shape
Out[54]:
(4,)
In [55]:
z1.size
Out[55]:
4
In [56]:
x = 20
not np.any([x%i == 0 for i in range(2, x)])
Out[56]:
False

Matplotlib and Pyplot

In [57]:
import matplotlib.pyplot as plt
In [58]:
plt.plot([0,3,4,6,17]);
In [59]:
x = np.linspace(0,10,20)
type(x)
Out[59]:
numpy.ndarray
In [60]:
y = x**2.0
In [61]:
x
Out[61]:
array([ 0.        ,  0.52631579,  1.05263158,  1.57894737,  2.10526316,
        2.63157895,  3.15789474,  3.68421053,  4.21052632,  4.73684211,
        5.26315789,  5.78947368,  6.31578947,  6.84210526,  7.36842105,
        7.89473684,  8.42105263,  8.94736842,  9.47368421, 10.        ])
In [62]:
y
Out[62]:
array([  0.        ,   0.27700831,   1.10803324,   2.49307479,
         4.43213296,   6.92520776,   9.97229917,  13.5734072 ,
        17.72853186,  22.43767313,  27.70083102,  33.51800554,
        39.88919668,  46.81440443,  54.29362881,  62.32686981,
        70.91412742,  80.05540166,  89.75069252, 100.        ])
In [63]:
plt.plot(x,y)
Out[63]:
[<matplotlib.lines.Line2D at 0x7f1a28243518>]
In [64]:
y1 = x ** 1.5
In [69]:
plt.plot(x,y, 'bo-', linewidth = 2, markersize=12)
Out[69]:
[<matplotlib.lines.Line2D at 0x7f1a27e70748>]
In [66]:
plt.plot(x,y1, 'gs-', linewidth = 2, markersize=12)
Out[66]:
[<matplotlib.lines.Line2D at 0x7f1a27f5d0f0>]
In [67]:
plt.plot([0,1,2],[0,1,4],"rd-")
Out[67]:
[<matplotlib.lines.Line2D at 0x7f1a27f392e8>]
In [78]:
plt.plot(x,y, 'bo-', linewidth = 2, markersize=8, label="First")
plt.plot(x,y1, 'gs-', linewidth = 2, markersize=8, label="Second")

plt.xlabel('$X$')
plt.ylabel('$Y$')
xmin = -0.5
xmax = 10.5
ymin = -5
ymax = 105
plt.axis([xmin, xmax, ymin, ymax])
plt.legend(loc = "upper left")
plt.savefig('myplot.pdf')

Plotting Using Logarithmic Axes

In [81]:
plt.loglog(x,y, 'bo-', linewidth = 2, markersize=8, label="First")
plt.loglog(x,y1, 'gs-', linewidth = 2, markersize=8, label="Second")
plt.xlabel('$X$')
plt.ylabel('$Y$')
plt.legend(loc = "upper left")
Out[81]:
<matplotlib.legend.Legend at 0x7f1a26f06978>
In [94]:
x = np.linspace(-1,1,40)
y = x ** 3
y1 = x ** 4
In [95]:
plt.loglog(x,y, 'bo-', linewidth = 2, markersize=8, label="First")
plt.loglog(x,y1, 'gs-', linewidth = 2, markersize=8, label="Second")
plt.xlabel('$X$')
plt.ylabel('$Y$')
plt.legend(loc = "upper left")
Out[95]:
<matplotlib.legend.Legend at 0x7f1a25bf57f0>
In [96]:
x = np.logspace(0,1,10)
y = x**2
plt.loglog(x,y,"bo-")
Out[96]:
[<matplotlib.lines.Line2D at 0x7f1a25a7e358>]

Generating Histograms

In [99]:
x = np.random.normal(size = 1000)
In [100]:
plt.hist(x)
Out[100]:
(array([ 16.,  52., 159., 259., 250., 186.,  56.,  17.,   3.,   2.]),
 array([-2.77862836, -2.0868003 , -1.39497225, -0.70314419, -0.01131613,
         0.68051192,  1.37233998,  2.06416804,  2.75599609,  3.44782415,
         4.13965221]),
 <a list of 10 Patch objects>)
In [102]:
plt.hist(x, normed = True, bins = np.linspace(-5, 5, 21));
In [103]:
x = np.random.gamma(2, 3, 100000)
plt.hist(x, bins = 30)
Out[103]:
(array([9.4290e+03, 1.7660e+04, 1.8274e+04, 1.5304e+04, 1.1730e+04,
        8.6140e+03, 6.1790e+03, 4.3140e+03, 2.8340e+03, 1.9860e+03,
        1.2610e+03, 8.9100e+02, 5.5500e+02, 3.4600e+02, 2.1700e+02,
        1.4800e+02, 1.0100e+02, 6.0000e+01, 3.6000e+01, 1.9000e+01,
        1.3000e+01, 1.3000e+01, 9.0000e+00, 3.0000e+00, 1.0000e+00,
        1.0000e+00, 1.0000e+00, 0.0000e+00, 0.0000e+00, 1.0000e+00]),
 array([1.55373861e-02, 1.54320910e+00, 3.07088082e+00, 4.59855253e+00,
        6.12622425e+00, 7.65389596e+00, 9.18156768e+00, 1.07092394e+01,
        1.22369111e+01, 1.37645828e+01, 1.52922545e+01, 1.68199263e+01,
        1.83475980e+01, 1.98752697e+01, 2.14029414e+01, 2.29306131e+01,
        2.44582848e+01, 2.59859566e+01, 2.75136283e+01, 2.90413000e+01,
        3.05689717e+01, 3.20966434e+01, 3.36243151e+01, 3.51519868e+01,
        3.66796586e+01, 3.82073303e+01, 3.97350020e+01, 4.12626737e+01,
        4.27903454e+01, 4.43180171e+01, 4.58456889e+01]),
 <a list of 30 Patch objects>)
In [106]:
plt.hist(x, bins = 30, normed = True)
Out[106]:
(array([6.17213758e-02, 1.15600753e-01, 1.19619941e-01, 1.00178591e-01,
        7.67835123e-02, 5.63864599e-02, 4.04471716e-02, 2.82390513e-02,
        1.85511060e-02, 1.30001752e-02, 8.25439122e-03, 5.83240490e-03,
        3.63297948e-03, 2.26488451e-03, 1.42046225e-03, 9.68794529e-04,
        6.61136807e-04, 3.92754539e-04, 2.35652723e-04, 1.24372271e-04,
        8.50968167e-05, 8.50968167e-05, 5.89131808e-05, 1.96377269e-05,
        6.54590898e-06, 6.54590898e-06, 6.54590898e-06, 0.00000000e+00,
        0.00000000e+00, 6.54590898e-06]),
 array([1.55373861e-02, 1.54320910e+00, 3.07088082e+00, 4.59855253e+00,
        6.12622425e+00, 7.65389596e+00, 9.18156768e+00, 1.07092394e+01,
        1.22369111e+01, 1.37645828e+01, 1.52922545e+01, 1.68199263e+01,
        1.83475980e+01, 1.98752697e+01, 2.14029414e+01, 2.29306131e+01,
        2.44582848e+01, 2.59859566e+01, 2.75136283e+01, 2.90413000e+01,
        3.05689717e+01, 3.20966434e+01, 3.36243151e+01, 3.51519868e+01,
        3.66796586e+01, 3.82073303e+01, 3.97350020e+01, 4.12626737e+01,
        4.27903454e+01, 4.43180171e+01, 4.58456889e+01]),
 <a list of 30 Patch objects>)
In [109]:
plt.hist(x, bins = 30, cumulative = True, normed = True, histtype = 'step')
Out[109]:
(array([0.09429, 0.27089, 0.45363, 0.60667, 0.72397, 0.81011, 0.8719 ,
        0.91504, 0.94338, 0.96324, 0.97585, 0.98476, 0.99031, 0.99377,
        0.99594, 0.99742, 0.99843, 0.99903, 0.99939, 0.99958, 0.99971,
        0.99984, 0.99993, 0.99996, 0.99997, 0.99998, 0.99999, 0.99999,
        0.99999, 1.     ]),
 array([1.55373861e-02, 1.54320910e+00, 3.07088082e+00, 4.59855253e+00,
        6.12622425e+00, 7.65389596e+00, 9.18156768e+00, 1.07092394e+01,
        1.22369111e+01, 1.37645828e+01, 1.52922545e+01, 1.68199263e+01,
        1.83475980e+01, 1.98752697e+01, 2.14029414e+01, 2.29306131e+01,
        2.44582848e+01, 2.59859566e+01, 2.75136283e+01, 2.90413000e+01,
        3.05689717e+01, 3.20966434e+01, 3.36243151e+01, 3.51519868e+01,
        3.66796586e+01, 3.82073303e+01, 3.97350020e+01, 4.12626737e+01,
        4.27903454e+01, 4.43180171e+01, 4.58456889e+01]),
 <a list of 1 Patch objects>)

Multiple Histograms into one Figure

In [111]:
plt.figure()
plt.subplot(221)
plt.hist(x, bins = 30)
plt.subplot(222)
plt.hist(x, bins = 30, normed = True)
plt.subplot(223)
plt.hist(x, bins = 30, cumulative = 30)
plt.subplot(224)
plt.hist(x, bins = 30, normed = True, cumulative = True, histtype = 'step')
Out[111]:
(array([0.09429, 0.27089, 0.45363, 0.60667, 0.72397, 0.81011, 0.8719 ,
        0.91504, 0.94338, 0.96324, 0.97585, 0.98476, 0.99031, 0.99377,
        0.99594, 0.99742, 0.99843, 0.99903, 0.99939, 0.99958, 0.99971,
        0.99984, 0.99993, 0.99996, 0.99997, 0.99998, 0.99999, 0.99999,
        0.99999, 1.     ]),
 array([1.55373861e-02, 1.54320910e+00, 3.07088082e+00, 4.59855253e+00,
        6.12622425e+00, 7.65389596e+00, 9.18156768e+00, 1.07092394e+01,
        1.22369111e+01, 1.37645828e+01, 1.52922545e+01, 1.68199263e+01,
        1.83475980e+01, 1.98752697e+01, 2.14029414e+01, 2.29306131e+01,
        2.44582848e+01, 2.59859566e+01, 2.75136283e+01, 2.90413000e+01,
        3.05689717e+01, 3.20966434e+01, 3.36243151e+01, 3.51519868e+01,
        3.66796586e+01, 3.82073303e+01, 3.97350020e+01, 4.12626737e+01,
        4.27903454e+01, 4.43180171e+01, 4.58456889e+01]),
 <a list of 1 Patch objects>)
In [ ]:
 

 

Python Libraries Used in Research

How I built EventMe – My Udacity Success Story


Ever wished that you had an app that will have all the events happening around you at your finger tips? If yes, the answer is EventMe.

Motivation

This was my final project for Udacity’s Android Nanodegree program. The Capstone Project phase helped me showcase my idea as a working Android app.

App Summary

EventMe determines events happening within a defined radius of the User’s current location. The intended User is anyone who wishes to learn about events happening in a given area. People who have just moved to a new town might find this app useful. Also, Uber/Lyft drivers who want to know where demand might be high for rides could also find this app useful.

Want to try it out?

EventMe GitHub Repo

How to develop an Android Audio Playback App


I thought I was done developing my Music Player app until I hit upon few scenarios that were  a bit embarrassing. In hindsight, it was obvious. You will hate your app if you don’t pause audio playback when the phone rings. So how do you handle such a scenario? “Request the Audio Focus”.

Audio focus refers to the assumption that only one thing should be playing at a time. Which means that the system needs a way to track which apps are currently playing audio. Audio focus goes by the adage  — when you’re holding it, you get to speak. But the system will take it away when it’s someone else’s turn.

You can manage audio focus for your app with AudioManager. When you’re ready to play something, you simply request it (and when you’re done, remember to release it). When audio focus is granted, you can have your playback. But, as I said, the system may take the audio focus back, either temporarily or permanently. So you need an OnAudioFocusChangeListener to keep track of your status and react to those changes. Wondering, how to put all this together, here’s some demo code that essentially translates “english” colors to a “regional” language pronunciation.

public class AudioActivity extends AppCompatActivity {

    /** Handles playback of all the sound files */
    private MediaPlayer mMediaPlayer;

    /** Handles audio focus when playing a sound file */
    private AudioManager mAudioManager;

    /**
     * This listener gets triggered when the {@link MediaPlayer} has completed
     * playing the audio file.
     */
    private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            // Now that the sound file has finished playing, release the media player resources.
            releaseMediaPlayer();
        }
    };

    /**
     * This listener gets triggered whenever the audio focus changes
     * (i.e., we gain or lose audio focus because of another app or device).
     */
    private AudioManager.OnAudioFocusChangeListener mOnAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
        @Override
        public void onAudioFocusChange(int focusChange) {
            if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT ||
                    focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
                // The AUDIOFOCUS_LOSS_TRANSIENT case means that we've lost audio focus for a
                // short amount of time. The AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK case means that
                // our app is allowed to continue playing sound but at a lower volume. We'll treat
                // both cases the same way because our app is playing short sound files.

                // Pause playback and reset player to the start of the file. That way, we can
                // play the word from the beginning when we resume playback.
                mMediaPlayer.pause();
                mMediaPlayer.seekTo(0);
            } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
                // The AUDIOFOCUS_GAIN case means we have regained focus and can resume playback.
                mMediaPlayer.start();
            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
                // The AUDIOFOCUS_LOSS case means we've lost audio focus and
                // Stop playback and clean up resources
                releaseMediaPlayer();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.word_list);

        // Create and setup the {@link AudioManager} to request audio focus
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

        // Create a list of words
        final ArrayList<Word> words = new ArrayList<Word>();
        words.add(new Word("red", "weṭeṭṭi", R.drawable.color_red, R.raw.color_red));
        words.add(new Word("mustard yellow", "chiwiiṭә", R.drawable.color_mustard_yellow,
                R.raw.color_mustard_yellow));
        words.add(new Word("dusty yellow", "ṭopiisә", R.drawable.color_dusty_yellow,
                R.raw.color_dusty_yellow));
        words.add(new Word("green", "chokokki", R.drawable.color_green, R.raw.color_green));
        words.add(new Word("brown", "ṭakaakki", R.drawable.color_brown, R.raw.color_brown));
        words.add(new Word("gray", "ṭopoppi", R.drawable.color_gray, R.raw.color_gray));
        words.add(new Word("black", "kululli", R.drawable.color_black, R.raw.color_black));
        words.add(new Word("white", "kelelli", R.drawable.color_white, R.raw.color_white));

        // Create an {@link WordAdapter}, whose data source is a list of {@link Word}s. The
        // adapter knows how to create list items for each item in the list.
        WordAdapter adapter = new WordAdapter(this, words, R.color.category_colors);

        // Find the {@link ListView} object in the view hierarchy of the {@link Activity}.
        // There should be a {@link ListView} with the view ID called list, which is declared in the
        // word_list.xml layout file.
        ListView listView = (ListView) findViewById(R.id.list);

        // Make the {@link ListView} use the {@link WordAdapter} we created above, so that the
        // {@link ListView} will display list items for each {@link Word} in the list.
        listView.setAdapter(adapter);

        // Set a click listener to play the audio when the list item is clicked on
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                // Release the media player if it currently exists because we are about to
                // play a different sound file
                releaseMediaPlayer();

                // Get the {@link Word} object at the given position the user clicked on
                Word word = words.get(position);

                // Request audio focus so in order to play the audio file. The app needs to play a
                // short audio file, so we will request audio focus with a short amount of time
                // with AUDIOFOCUS_GAIN_TRANSIENT.
                int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener,
                        AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

                if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                    // We have audio focus now.

                    // Create and setup the {@link MediaPlayer} for the audio resource associated
                    // with the current word
                    mMediaPlayer = MediaPlayer.create(ColorsActivity.this, word.getAudioResourceId());

                    // Start the audio file
                    mMediaPlayer.start();

                    // Setup a listener on the media player, so that we can stop and release the
                    // media player once the sound has finished playing.
                    mMediaPlayer.setOnCompletionListener(mCompletionListener);
                }
            }
        });
    }

    @Override
    protected void onStop() {
        super.onStop();
        // When the activity is stopped, release the media player resources because we won't
        // be playing any more sounds.
        releaseMediaPlayer();
    }

    /**
     * Clean up the media player by releasing its resources.
     */
    private void releaseMediaPlayer() {
        // If the media player is not null, then it may be currently playing a sound.
        if (mMediaPlayer != null) {
            // Regardless of the current state of the media player, release its resources
            // because we no longer need it.
            mMediaPlayer.release();

            // Set the media player back to null. For our code, we've decided that
            // setting the media player to null is an easy way to tell that the media player
            // is not configured to play an audio file at the moment.
            mMediaPlayer = null;

            // Regardless of whether or not we were granted audio focus, abandon it. This also
            // unregisters the AudioFocusChangeListener so we don't get anymore callbacks.
            mAudioManager.abandonAudioFocus(mOnAudioFocusChangeListener);
        }
    }
}