AudioRecord的raw转8位wav或mp3

AudioRecord在android设备8位是不一样支持,对于有时需要和其他设备进行传输(只能接受8位)也为了压缩等问题,不得不把16位的原数据进行转换。
       AudioRecord的具体使用办法就不粘出来了,度娘那里有不少。
       1.16位数据转8位数据  这里得到8位wav
        public void copyWaveFile() {
                File file = new File(AudioName);
                if (!file.exists()) {
                        return;
                }
                long totalAudioLen = 0;
                long totalDataLen = totalAudioLen + 36;
                long longSampleRate = frequence;
                int channels = 1;
                long byteRate = 8 * frequence * channels / 8;
                try {
                        int dateLength = (int) (file.length() / 2);
                        short[] data = new short[dateLength];
                        byte[] Bytedata=new byte[dateLength];
                        InputStream is = new FileInputStream(file);
                        BufferedInputStream bis = new BufferedInputStream(is);
                        DataInputStream dis = new DataInputStream(bis);
                        FileOutputStream out = new FileOutputStream(NewAudioName);
                        totalAudioLen = dateLength;
                        totalDataLen = totalAudioLen + 36;
                        WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
                                        longSampleRate, channels, byteRate);
                        int size=0;
                        int i = 0;
                        while (dis.available() > 0) {
                                data = dis.readShort();
                                // 16位转8位 保留前八位 第一位取反
                                if (data > 0x8000) {
                                        Bytedata = (byte) (0x80 - (0xff - data >> 8));
                                } else {
                                        Bytedata = (byte) (0x80 + (data>> 8));
                                }
                                i++;
                        }
                        out.write(Bytedata);
                        dis.close();
                        out.close();
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
        /**
         * 8位的wav文件头 这里提供一个头信息。插入这些信息就可以得到可以播放的文件。每种格式的文件都有自己特有的头文件。
         */
        private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen,
                        long totalDataLen, long longSampleRate, int channels, long byteRate)
                        throws IOException {
                byte[] header = new byte[44];
                header[0] = 'R'; // RIFF/WAVE header
                header[1] = 'I';
                header[2] = 'F';
                header[3] = 'F';
                header[4] = (byte) (totalDataLen & 0xff);
                header[5] = (byte) ((totalDataLen >> 8) & 0xff);
                header[6] = (byte) ((totalDataLen >> 16) & 0xff);
                header[7] = (byte) ((totalDataLen >> 24) & 0xff);
                header[8] = 'W';
                header[9] = 'A';
                header[10] = 'V';
                header[11] = 'E';
                header[12] = 'f'; // 'fmt ' chunk
                header[13] = 'm';
                header[14] = 't';
                header[15] = ' ';
                header[16] = 16; // 4 bytes: size of 'fmt ' chunk
                header[17] = 0;
                header[18] = 0;
                header[19] = 0;
                header[20] = 1; // format = 1
                header[21] = 0;
                header[22] = (byte) channels;
                header[23] = 0;
                header[24] = (byte) (longSampleRate & 0xff);
                header[25] = (byte) ((longSampleRate >> 8) & 0xff);
                header[26] = (byte) ((longSampleRate >> 16) & 0xff);
                header[27] = (byte) ((longSampleRate >> 24) & 0xff);
                header[28] = (byte) (byteRate & 0xff);
                header[29] = (byte) ((byteRate >> 8) & 0xff);
                header[30] = (byte) ((byteRate >> 16) & 0xff);
                header[31] = (byte) ((byteRate >> 24) & 0xff);
                header[32] = (byte) (1 * 8 / 8); // block align
                header[33] = 0;
                header[34] = 8; // bits per sample
                header[35] = 0;
                header[36] = 'd';
                header[37] = 'a';
                header[38] = 't';
                header[39] = 'a';
                header[40] = (byte) (totalAudioLen & 0xff);
                header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
                header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
                header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
                out.write(header, 0, 44);
        }
  2.转换成MP3,是将lame移植到android上,这里用了别人打包好了的[使用Lame把音频文件转换成mp3格式](http://www.pocketdigi.com/20130306/996.html),里面有附带移植方法链接以及第三方包使用方法。这里转换成MP3
        public void writeMP3() {
                File file = new File(AudioName);
                if (!file.exists()) {
                        return;
                }
                FLameUtils lameUtils = new FLameUtils(1, frequence, 96);
                lameUtils.raw2mp3(AudioName, MP3Name);
        }
3.频谱,用到了FFT 快速傅里叶变换
public void fft(Complex[] xin, int N) {
                int f, m, N2, nm, i, k, j, L;// L:运算级数
                float p;
                int e2, le, B, ip;
                Complex w = new Complex();
                Complex t = new Complex();
                N2 = N / 2;// 每一级中蝶形的个数,同时也代表m位二进制数最高位的十进制权值
                f = N;// f是为了求流程的级数而设立的
                for (m = 1; (f = f / 2) != 1; m++)
                        ; // 得到流程图的共几级
                nm = N - 2;
                j = N2;
                /****** 倒序运算——雷德算法 ******/
                for (i = 1; i <= nm; i++) {
                        if (i < j)// 防止重复交换
                        {
                                t = xin[j];
                                xin[j] = xin;
                                xin = t;
                        }
                        k = N2;
                        while (j >= k) {
                                j = j - k;
                                k = k / 2;
                        }
                        j = j + k;
                }
                /****** 蝶形图计算部分 ******/
                for (L = 1; L <= m; L++) // 从第1级到第m级
                {
                        e2 = (int) Math.pow(2, L);
                        // e2=(int)2.pow(L);
                        le = e2 + 1;
                        B = e2 / 2;
                        for (j = 0; j < B; j++) // j从0到2^(L-1)-1
                        {
                                p = 2 * pi / e2;
                                w.real = Math.cos(p * j);
                                // w.real=Math.cos((double)p*j); //系数W
                                w.image = Math.sin(p * j) * -1;
                                // w.imag = -sin(p*j);
                                for (i = j; i < N; i = i + e2) // 计算具有相同系数的数据
                                {
                                        ip = i + B; // 对应蝶形的数据间隔为2^(L-1)
                                        t = xin[ip].cc(w);
                                        xin[ip] = xin.cut(t);
                                        xin = xin.sum(t);
                                }
                        }
                }
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值