diff --git a/media/Audio/entry/src/main/java/ohos/samples/audio/slice/AudioRecorderSlice.java b/media/Audio/entry/src/main/java/ohos/samples/audio/slice/AudioRecorderSlice.java index 8454c7bbfab73c13cd0cfacf110cd29784d6622e..340cbd443420c753f064073d07ddd17fcf4a9c7a 100644 --- a/media/Audio/entry/src/main/java/ohos/samples/audio/slice/AudioRecorderSlice.java +++ b/media/Audio/entry/src/main/java/ohos/samples/audio/slice/AudioRecorderSlice.java @@ -24,8 +24,6 @@ import ohos.agp.components.Component; import ohos.agp.components.Text; import ohos.agp.window.dialog.ToastDialog; import ohos.app.dispatcher.task.TaskPriority; -import ohos.hiviewdfx.HiLog; -import ohos.hiviewdfx.HiLogLabel; import ohos.media.audio.AudioCapturer; import ohos.media.audio.AudioCapturerCallback; import ohos.media.audio.AudioCapturerConfig; @@ -33,6 +31,8 @@ import ohos.media.audio.AudioCapturerInfo; import ohos.media.audio.AudioDeviceDescriptor; import ohos.media.audio.AudioManager; import ohos.media.audio.AudioStreamInfo; +import ohos.samples.audio.utils.HiLogUtils; +import ohos.samples.audio.utils.ShellUtils; import java.io.File; import java.io.FileOutputStream; @@ -40,13 +40,11 @@ import java.io.IOException; import java.util.List; /** - * AudioCapturer + * AudioRecorderSlice */ public class AudioRecorderSlice extends AbilitySlice { private static final String TAG = AudioRecorderSlice.class.getName(); - private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG); - private static final int SAMPLE_RATE = 44100; private static final int BUFFER_SIZE = 1024; @@ -66,7 +64,7 @@ public class AudioRecorderSlice extends AbilitySlice { private final AudioCapturerCallback callback = new AudioCapturerCallback() { @Override public void onCapturerConfigChanged(List configs) { - HiLog.info(LABEL_LOG, "%{public}s", "on capturer config changed"); + HiLogUtils.info(TAG, "on capturer config changed"); } }; @@ -127,6 +125,9 @@ public class AudioRecorderSlice extends AbilitySlice { recordButton.setText("Start"); showTips("Stop record"); pathText.setText("Path:" + getFilesDir() + File.separator + "record.pcm"); + String wavPath = getFilesDir() + File.separator + "record.wav"; + ShellUtils.tranPcmToWavFile(file, wavPath); + pathText.setText("Path:" + getFilesDir() + File.separator + "record.wav"); } } @@ -149,8 +150,8 @@ public class AudioRecorderSlice extends AbilitySlice { bytes = new byte[BUFFER_SIZE]; outputStream.flush(); } - } catch (IOException exception) { - HiLog.error(LABEL_LOG, "%{public}s", "record exception"); + } catch (IOException exception) { + HiLogUtils.error(TAG, "record exception," + exception.getMessage()); } }); } diff --git a/media/Audio/entry/src/main/java/ohos/samples/audio/utils/HiLogUtils.java b/media/Audio/entry/src/main/java/ohos/samples/audio/utils/HiLogUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..c63a17cadd24f0d59f46055bdb598d92430b1763 --- /dev/null +++ b/media/Audio/entry/src/main/java/ohos/samples/audio/utils/HiLogUtils.java @@ -0,0 +1,43 @@ +package ohos.samples.audio.utils; + +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; + +import java.util.Objects; + +/** + * HiLogUtils + * + * @since 2021-08-27 + */ +public class HiLogUtils { + private static final String APP_NAME = "Audio"; + private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, APP_NAME); + public static final String LOG_FORMAT = "%{public}s:%{public}s"; + + private HiLogUtils() { + } + + public static void info(String className, String msg) { + HiLog.info(LABEL_LOG, LOG_FORMAT, getLogPrefix(className), msg); + } + + public static void error(String className, String msg) { + HiLog.error(LABEL_LOG, LOG_FORMAT, getLogPrefix(className), msg); + } + + private static String getLogPrefix(String tag) { + Thread currentThread = Thread.currentThread(); + String threadName = currentThread.getName(); + StackTraceElement[] stackTraceElements = currentThread.getStackTrace(); + int lineNum = 0; + for (int index = 0; index < stackTraceElements.length; index++) { + if (Objects.equals(stackTraceElements[index].getClassName(), HiLogUtils.class.getName()) + && stackTraceElements.length > index + 1 + && !Objects.equals(stackTraceElements[index + 1].getClassName(), HiLogUtils.class.getName())) { + lineNum = stackTraceElements[index + 1].getLineNumber(); + } + } + return "[" + threadName + "]" + "(" + tag + ".java" + lineNum + ")"; + } +} diff --git a/media/Audio/entry/src/main/java/ohos/samples/audio/utils/ShellUtils.java b/media/Audio/entry/src/main/java/ohos/samples/audio/utils/ShellUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..4dbad3ca33232f2e118b70ba8e4664893798dda7 --- /dev/null +++ b/media/Audio/entry/src/main/java/ohos/samples/audio/utils/ShellUtils.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 ohos.samples.audio.utils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * ShellUtils + * + * @since 2021-08-27 + */ +public class ShellUtils { + private static final String TAG = ShellUtils.class.getName(); + + private static final int HEADER_SIZE = 44; + + private static final int SAMPLE_RATE = 44100; + + private static final int BUFFER_SIZE = 1024 * 4; + + private static final int CHANNEL = 2; + + private static final int BITS_PRE_SAMPLE = 16; + + private static final int BIT = 8; + + private static final short FORMAT_TAG = 0x0001; + + private ShellUtils() { + } + + /** + * tranPcmToWavFile + * + * @param pcmFile File + * @param wavPath String + */ + public static void tranPcmToWavFile(File pcmFile, String wavPath) { + try (FileInputStream fis = new FileInputStream(pcmFile)) { + FileOutputStream fos = new FileOutputStream(wavPath); + int PCMSize = 0; + byte[] buf = new byte[BUFFER_SIZE]; + int size = fis.read(buf); + while (size != -1) { + PCMSize += size; + size = fis.read(buf); + } + fis.close(); + + // 填入参数,比特率等等。这里用的是16位双声道 44100 hz + WaveHeader header = new WaveHeader(); + + // 长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节) + header.fileLength = PCMSize + (HEADER_SIZE - BIT); + header.FmtHdrLeth = BITS_PRE_SAMPLE; + header.BitsPerSample = BITS_PRE_SAMPLE; + header.Channels = CHANNEL; + header.FormatTag = FORMAT_TAG; + header.SamplesPerSec = SAMPLE_RATE; + header.BlockAlign = (short) (header.Channels * header.BitsPerSample / BIT); + header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec; + header.DataHdrLeth = PCMSize; + byte[] h = header.getHeader(); + assert h.length == HEADER_SIZE; // WAV标准,头部应该是44字节 + fos.write(h, 0, h.length); // write header + + // write data stream + FileInputStream file = new FileInputStream(pcmFile); + size = file.read(buf); + while (size != -1) { + fos.write(buf, 0, size); + size = file.read(buf); + } + file.close(); + fos.close(); + if (pcmFile.delete()) { + HiLogUtils.error(TAG, "record exception"); + } + } catch (IOException e) { + HiLogUtils.error(TAG, e.getMessage()); + } + } + + /** + * WaveHeader + */ + static class WaveHeader { + public final char[] fileID = {'R', 'I', 'F', 'F'}; + public int fileLength; + public char[] wavTag = {'W', 'A', 'V', 'E'}; + public char[] FmtHdrID = {'f', 'm', 't', ' '}; + public int FmtHdrLeth; + public short FormatTag; + public short Channels; + public int SamplesPerSec; + public int AvgBytesPerSec; + public short BlockAlign; + public short BitsPerSample; + public char[] DataHdrID = {'d', 'a', 't', 'a'}; + public int DataHdrLeth; + + public byte[] getHeader() throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + writeChar(bos, fileID); + writeInt(bos, fileLength); + writeChar(bos, wavTag); + writeChar(bos, FmtHdrID); + writeInt(bos, FmtHdrLeth); + writeShort(bos, FormatTag); + writeShort(bos, Channels); + writeInt(bos, SamplesPerSec); + writeInt(bos, AvgBytesPerSec); + writeShort(bos, BlockAlign); + writeShort(bos, BitsPerSample); + writeChar(bos, DataHdrID); + writeInt(bos, DataHdrLeth); + bos.flush(); + byte[] r = bos.toByteArray(); + bos.close(); + return r; + } + + private void writeShort(ByteArrayOutputStream bos, int s) throws IOException { + // write short + byte[] mybyte = new byte[2]; + mybyte[1] = (byte) ((s << 16) >> 24); + mybyte[0] = (byte) ((s << 24) >> 24); + bos.write(mybyte); + } + + + private void writeInt(ByteArrayOutputStream bos, int n) throws IOException { + // write int + byte[] buf = new byte[4]; + buf[3] = (byte) (n >> 24); + buf[2] = (byte) ((n << 8) >> 24); + buf[1] = (byte) ((n << 16) >> 24); + buf[0] = (byte) ((n << 24) >> 24); + bos.write(buf); + } + + private void writeChar(ByteArrayOutputStream bos, char[] id) { + for (char c : id) { + bos.write(c); + } + } + } +}