浏览代码

修改作品合成音频波浪效果

Pq 9 月之前
父节点
当前提交
4e7af05975

+ 70 - 80
musicMerge/src/main/java/com/cooleshow/musicmerge/widget/MusicFrequencyView.java

@@ -5,44 +5,47 @@ import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.media.MediaPlayer;
+import android.graphics.Path;
+import android.graphics.RectF;
 import android.media.audiofx.Visualizer;
 import android.util.AttributeSet;
 import android.view.View;
 
+import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.SizeUtils;
 import com.cooleshow.musicmerge.R;
 
 import androidx.annotation.Nullable;
 
 /**
- * author by LiuGuo
+ *
  * on 2021/4/13
  * 自定义组件:音乐频谱显示组件
  * API-> setMediaPlayer()  外层设置路径 播放之后 自动显示频谱效果
  */
 public class MusicFrequencyView extends View {
     private static final String TAG = "MusicFrequencyView";
-    private int LUMP_COUNT = 60;
-    private int LUMP_WIDTH = SizeUtils.dp2px(5);
+    private int LUMP_COUNT = 120;
+    private int LUMP_WIDTH = SizeUtils.dp2px(1.5f);
+    ;
     private int LUMP_SPACE = SizeUtils.dp2px(3);
     private int LUMP_SIZE = LUMP_WIDTH + LUMP_SPACE;
     private int LUMP_MAX_HEIGHT = SizeUtils.dp2px(80);
-    private int LUMP_MIN_HEIGHT = SizeUtils.dp2px(5);
-    private float SCALE = 1.0f;
+    private int LUMP_MIN_HEIGHT = SizeUtils.dp2px(3);
+    private float SCALE = 0.95f;
     private int widthsize;
     private int heightsize;
-    private Paint paint;
     private Visualizer visualizer;
     private int itemColor = Color.WHITE;
     private Paint paint1;
-    private float mi;
+    protected RectF mRect;
 
     public MusicFrequencyView(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
         TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.musicView);
-//        itemColor = ta.getColor(R.styleable.musicView_itemColor, Color.parseColor("#269EFE"));
         itemColor = ta.getColor(R.styleable.musicView_itemColor, Color.WHITE);
+        mRect = new RectF();
+        waveData = new float[LUMP_COUNT];
     }
 
 
@@ -56,36 +59,37 @@ public class MusicFrequencyView extends View {
 
 
     @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        mRect.set(0, 0, getWidth(), getHeight());
+    }
+
+
+    @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-
-//        Log.e(TAG, "" + heightsize + "==" + widthsize);
-        if (waveData != null) {
-//            Log.e(TAG, "waveData" + waveData.length);
-        }
-        for (int i = 0; i < LUMP_COUNT; i++) {
-            if (waveData == null) {
-                canvas.drawRect((LUMP_WIDTH + LUMP_SPACE) * i,
-                        LUMP_MAX_HEIGHT - LUMP_MIN_HEIGHT,
-                        (LUMP_WIDTH + LUMP_SPACE) * i + LUMP_WIDTH,
-                        LUMP_MAX_HEIGHT,
-                        paint1);
-                continue;
-            }
-            drawLump(canvas, i, false);
+        //因为外部宽度是写死的,不调整坐标算法,最后一个可能绘制不全,暂时不绘制最后一个吧
+        for (int i = 1; i <= LUMP_COUNT-1; i++) {
+//            canvas.drawLine(mRect.width() * i / LUMP_COUNT, mRect.height() / 2, mRect.width() * i / LUMP_COUNT, -LUMP_MIN_HEIGHT + mRect.height() / 2 - SCALE * waveData[i], paint1);
+//            canvas.drawLine(mRect.width() * i / LUMP_COUNT, mRect.height() / 2, mRect.width() * i / LUMP_COUNT, LUMP_MIN_HEIGHT + mRect.height() / 2 + SCALE * waveData[i], paint1);
+            canvas.drawLine(mRect.width() * i / LUMP_COUNT, -LUMP_MIN_HEIGHT + mRect.height() / 2 - SCALE * waveData[i-1], mRect.width() * i / LUMP_COUNT, LUMP_MIN_HEIGHT + mRect.height() / 2 + SCALE * waveData[i - 1], paint1);
         }
     }
 
+    private Path getPath(float startX, float startY, float endX, float endY, Paint paint) {
+        Path path = new Path();
+        paint.setStrokeCap(Paint.Cap.SQUARE);
+        path.moveTo(startY, startY);
+        path.lineTo(endX / 2, endY / 2);
+        paint.setStrokeCap(Paint.Cap.ROUND);
+        path.lineTo(endX, endY);
+        return path;
+    }
+
 
     private Visualizer.OnDataCaptureListener dataCaptureListener = new Visualizer.OnDataCaptureListener() {
         @Override
         public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
-//            Log.i("xiaozhu", "waveform" + waveform.length);
-            long v = 0;
-            for (int i = 0; i < waveform.length; i++) {
-                v += Math.pow(waveform[i], 2);
-            }
-            double volume = 10 * Math.log10(v / (double) waveform.length);
         }
 
         @Override
@@ -94,7 +98,7 @@ public class MusicFrequencyView extends View {
         }
     };
 
-    private byte[] waveData;
+    private float[] waveData;
 
     private void setWaveData(byte[] fft) {
         waveData = readyData(fft);
@@ -103,61 +107,59 @@ public class MusicFrequencyView extends View {
     }
 
     /**
-     * 绘制矩形条
+     * 预处理数据
+     *
+     * @return
      */
-    private void drawLump(Canvas canvas, int i, boolean reversal) {
-        int minus = reversal ? -1 : 1;
-
-        if (waveData[i] < 0) {
-//            LOG.i(TAG, "waveData[i] < 0 data: %s" + waveData[i]);
-        }
-        float top = (LUMP_MAX_HEIGHT - (LUMP_MIN_HEIGHT + waveData[i] * SCALE) * minus);
+    private float[] readyData(byte[] fft) {
+        float[] model = new float[fft.length / 2 + 1];
+        model[0] = (float) Math.abs(fft[1]);
+        int j = 1;
 
+        for (int i = 2; i < LUMP_COUNT * 2; ) {
 
-        canvas.drawLine(LUMP_SIZE * i, LUMP_MAX_HEIGHT,
-                LUMP_SIZE * i, top, paint1);
-//        canvas.drawRect(LUMP_SIZE * i,
-//                top,
-//                LUMP_SIZE * i + LUMP_WIDTH,
-//                LUMP_MAX_HEIGHT,
-//                paint1);
+            model[j] = (float) Math.hypot(fft[i], fft[i + 1]);
+            i += 2;
+            j++;
+            model[j] = Math.abs(model[j]);
+        }
+        LOG.i(TAG,"model:"+model.length);
+        float[] results = hananianWindow(model, 2);
+        LOG.i(TAG,"results:"+results.length);
+        return results;
     }
 
-    /**
-     * 预处理数据
-     *
-     * @return
-     */
-    private byte[] readyData(byte[] fft) {
-        byte[] newData = new byte[LUMP_COUNT];
-        byte abs;
-        for (int i = 0; i < LUMP_COUNT; i++) {
-            abs = (byte) Math.abs(fft[i]);
-            //描述:Math.abs -128时越界
-            newData[i] = abs < 0 ? 127 : abs;
+    public static float[] hananianWindow(float[] data, int windowSize) {
+        float[] windowData = new float[data.length - windowSize + 1];
+        for (int i = 0; i < windowData.length; i++) {
+            float sum = 0;
+            for (int j = 0; j < windowSize; j++) {
+                sum += data[i + j];
+            }
+            windowData[i] = sum / windowSize;
         }
-        return newData;
+        return windowData;
     }
 
     /**
      * 只需传入 mediaPlayer 即可
      *
-     * @param mediaPlayer
+     * @param
      */
     public void setMediaPlayer(final int audioSessionId) {
-        try{
+        try {
             if (visualizer == null) {
                 visualizer = new Visualizer(audioSessionId);
 
                 int captureSize = Visualizer.getCaptureSizeRange()[1];
-                int captureRate = Visualizer.getMaxCaptureRate() * 3 / 4;
+                int captureRate = Visualizer.getMaxCaptureRate() / 2;
                 // 3:设置参数
                 visualizer.setCaptureSize(captureSize);
-                visualizer.setDataCaptureListener(dataCaptureListener, captureRate, true, true);
+                visualizer.setDataCaptureListener(dataCaptureListener, captureRate, false, true);
                 visualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED);
                 visualizer.setEnabled(true);
             }
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -188,25 +190,13 @@ public class MusicFrequencyView extends View {
      * 初始化画笔
      */
     void init() {
-        setLayerType(LAYER_TYPE_SOFTWARE, null); //部分手机不显示阴影效果 配合setShadowLayer
-        paint = new Paint();
-        paint.setAntiAlias(true);
-        paint.setColor(itemColor);
-        paint.setStyle(Paint.Style.FILL);
-        paint.setFilterBitmap(true);
-        paint.setShadowLayer(2, 9, 5, Color.parseColor("#55000000"));
-        paint.setStrokeWidth(heightsize / 100f);
-
-
         paint1 = new Paint();
-        paint1.setAntiAlias(true);
+        paint1.setStrokeWidth(LUMP_WIDTH);
         paint1.setColor(itemColor);
         paint1.setStrokeCap(Paint.Cap.ROUND);
-        paint1.setTextAlign(Paint.Align.LEFT);
+        paint1.setAntiAlias(true);
         paint1.setStyle(Paint.Style.FILL);
-//        paint1.setStrokeWidth(heightsize / 100f);
-        paint1.setStrokeWidth(LUMP_WIDTH);
-
-
+        paint1.setStrokeJoin(Paint.Join.BEVEL);
+//        paint1.setMaskFilter(new BlurMaskFilter(5, BlurMaskFilter.Blur.SOLID));
     }
 }

+ 8 - 5
musicMerge/src/main/res/layout/ac_music_handle_layout.xml

@@ -74,13 +74,16 @@
 
 
     <com.cooleshow.musicmerge.widget.MusicFrequencyView
-        android:layout_width="358dp"
         android:id="@+id/music_frequency_view"
-        app:layout_constraintRight_toLeftOf="@+id/fl_setting"
-        app:layout_constraintLeft_toLeftOf="parent"
+        android:layout_width="365dp"
+        android:layout_height="80dp"
+        android:layout_marginTop="30dp"
+        android:visibility="gone"
+        app:itemColor="@color/white"
         app:layout_constraintBottom_toBottomOf="@+id/fl_ablum"
-        app:layout_constraintTop_toTopOf="@+id/fl_ablum"
-        android:layout_height="80dp"/>
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/fl_setting"
+        app:layout_constraintTop_toTopOf="@+id/fl_ablum" />
     
     <ImageView
         android:id="@+id/iv_gramophone_bg"