1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.sample.oboe.manualtest; 18 19 import android.content.Context; 20 import android.util.AttributeSet; 21 import android.view.LayoutInflater; 22 23 24 import android.view.View; 25 import android.widget.RadioButton; 26 import android.widget.SeekBar; 27 import android.widget.TextView; 28 import android.widget.LinearLayout; 29 30 public class BufferSizeView extends LinearLayout { 31 private OboeAudioStream mStream; 32 33 private static final int FADER_THRESHOLD_MAX = 1000; // must match layout 34 private static final int USE_FADER = -1; 35 private static final int DEFAULT_NUM_BURSTS = 2; 36 private TextView mTextLabel; 37 private SeekBar mFader; 38 private ExponentialTaper mTaper; 39 private RadioButton mBufferSizeRadio1; 40 private RadioButton mBufferSizeRadio2; 41 private RadioButton mBufferSizeRadio3; 42 private int mCachedCapacity; 43 private int mFramesPerBurst; 44 private int mNumBursts; 45 46 private SeekBar.OnSeekBarChangeListener mFaderListener = new SeekBar.OnSeekBarChangeListener() { 47 @Override 48 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 49 mNumBursts = USE_FADER; 50 updateRadioButtons(); 51 setBufferSizeByPosition(progress); 52 } 53 54 @Override 55 public void onStartTrackingTouch(SeekBar seekBar) { 56 } 57 58 @Override 59 public void onStopTrackingTouch(SeekBar seekBar) { 60 } 61 }; 62 BufferSizeView(Context context)63 public BufferSizeView(Context context) { 64 super(context); 65 initializeViews(context); 66 } 67 BufferSizeView(Context context, AttributeSet attrs)68 public BufferSizeView(Context context, AttributeSet attrs) { 69 super(context, attrs); 70 initializeViews(context); 71 } 72 BufferSizeView(Context context, AttributeSet attrs, int defStyle)73 public BufferSizeView(Context context, 74 AttributeSet attrs, 75 int defStyle) { 76 super(context, attrs, defStyle); 77 initializeViews(context); 78 } 79 setFaderNormalizedProgress(double fraction)80 void setFaderNormalizedProgress(double fraction) { 81 mFader.setProgress((int) (fraction * FADER_THRESHOLD_MAX)); 82 } 83 84 /** 85 * Inflates the views in the layout. 86 * 87 * @param context the current context for the view. 88 */ initializeViews(Context context)89 private void initializeViews(Context context) { 90 LayoutInflater inflater = (LayoutInflater) context 91 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 92 inflater.inflate(R.layout.buffer_size_view, this); 93 94 mTextLabel = (TextView) findViewById(R.id.textThreshold); 95 mFader = (SeekBar) findViewById(R.id.faderBufferSize); 96 mFader.setOnSeekBarChangeListener(mFaderListener); 97 mTaper = new ExponentialTaper(0.0, 1.0, 10.0); 98 mFader.setProgress(0); 99 100 mBufferSizeRadio1 = (RadioButton) findViewById(R.id.bufferSize1); 101 mBufferSizeRadio1.setOnClickListener(new View.OnClickListener() { 102 @Override 103 public void onClick(View view) { 104 onSizeRadioButtonClicked(view, 1); 105 } 106 }); 107 mBufferSizeRadio2 = (RadioButton) findViewById(R.id.bufferSize2); 108 mBufferSizeRadio2.setOnClickListener(new View.OnClickListener() { 109 @Override 110 public void onClick(View view) { 111 onSizeRadioButtonClicked(view, 2); 112 } 113 }); 114 mBufferSizeRadio3 = (RadioButton) findViewById(R.id.bufferSize3); 115 mBufferSizeRadio3.setOnClickListener(new View.OnClickListener() { 116 @Override 117 public void onClick(View view) { 118 onSizeRadioButtonClicked(view, 3); 119 } 120 }); 121 mNumBursts = DEFAULT_NUM_BURSTS; 122 updateRadioButtons(); 123 updateBufferSize(); 124 } 125 updateRadioButtons()126 public void updateRadioButtons() { 127 if (mBufferSizeRadio3 != null) { 128 mBufferSizeRadio1.setChecked(mNumBursts == 1); 129 mBufferSizeRadio2.setChecked(mNumBursts == 2); 130 mBufferSizeRadio3.setChecked(mNumBursts == 3); 131 } 132 } 133 onSizeRadioButtonClicked(View view, int numBursts)134 private void onSizeRadioButtonClicked(View view, int numBursts) { 135 boolean checked = ((RadioButton) view).isChecked(); 136 if (!checked) return; 137 mNumBursts = numBursts; 138 setBufferSizeByNumBursts(numBursts); 139 } 140 141 // sets mStream, mCachedCapacity and mFramesPerBurst onStreamOpened(OboeAudioStream stream)142 public void onStreamOpened(OboeAudioStream stream) { 143 mStream = stream; 144 if (mStream != null) { 145 int capacity = mStream.getBufferCapacityInFrames(); 146 if (capacity > 0) mCachedCapacity = capacity; 147 int framesPerBurst = mStream.getFramesPerBurst(); 148 if (framesPerBurst > 0) mFramesPerBurst = framesPerBurst; 149 } 150 updateBufferSize(); 151 } 152 setBufferSizeByNumBursts(int numBursts)153 private void setBufferSizeByNumBursts(int numBursts) { 154 int sizeFrames = -1; 155 if (mStream != null) { 156 int framesPerBurst = mStream.getFramesPerBurst(); 157 if (framesPerBurst > 0) { 158 sizeFrames = numBursts * framesPerBurst; 159 } 160 } 161 StringBuffer message = new StringBuffer(); 162 message.append("bufferSize = #" + numBursts); 163 164 setBufferSize(message, sizeFrames); 165 } 166 setBufferSizeByPosition(int progress)167 private void setBufferSizeByPosition(int progress) { 168 int sizeFrames = -1; 169 double normalizedThreshold = 0.0; 170 171 StringBuffer message = new StringBuffer(); 172 173 normalizedThreshold = mTaper.linearToExponential( 174 ((double) progress) / FADER_THRESHOLD_MAX); 175 if (normalizedThreshold < 0.0) normalizedThreshold = 0.0; 176 else if (normalizedThreshold > 1.0) normalizedThreshold = 1.0; 177 int percent = (int) (normalizedThreshold * 100); 178 message.append("bufferSize = " + percent + "%"); 179 180 if (mCachedCapacity > 0) { 181 sizeFrames = (int) (normalizedThreshold * mCachedCapacity); 182 } 183 setBufferSize(message, sizeFrames); 184 } 185 setBufferSize(StringBuffer message, int sizeFrames)186 private void setBufferSize(StringBuffer message, int sizeFrames) { 187 if (mStream != null) { 188 message.append(", " + sizeFrames); 189 if (mStream != null && sizeFrames >= 0) { 190 mStream.setBufferSizeInFrames(sizeFrames); 191 } 192 int bufferSize = mStream.getBufferSizeInFrames(); 193 if (bufferSize >= 0) { 194 message.append(" / " + bufferSize); 195 } 196 message.append(" / " + mCachedCapacity); 197 } 198 mTextLabel.setText(message.toString()); 199 } 200 updateBufferSize()201 private void updateBufferSize() { 202 if (mNumBursts == USE_FADER) { 203 int progress = mFader.getProgress(); 204 setBufferSizeByPosition(progress); 205 } else { 206 setBufferSizeByNumBursts(mNumBursts); 207 } 208 } 209 210 @Override setEnabled(boolean enabled)211 public void setEnabled(boolean enabled) { 212 super.setEnabled(enabled); 213 mFader.setEnabled(enabled); 214 } 215 } 216