diff --git a/README.md b/README.md index 1442170..cfd9213 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ English | 简体中文

-- 边录边转码MP3,默认启动系统自带[如果手机支持]的AEC、NC、AGC。 +- 边录边转码MP3,默认启动系统自带[如果手机支持]的AEC、NC、AGC,可以通过`enableAudioEffect`进行开启和关闭,除1.9.1是默认关闭的(因为部分手机外接麦克风时,如果是MIC,会没有声音),其他版本都是默认开启。 - 支持暂停,实时返回已**录制时长**和当前**声音大小**,已录制的那段音频是**可以播放**的. - 支持添加背景音乐,可以设置背景音乐声音的大小 - 可以使用默认耳机配置方式:如果没有连接耳机会只用外放的背景音乐,如果连接上了耳机,会使用写入合成背景音乐的方式 @@ -146,6 +146,11 @@ abstract class BaseRecorder { open fun setPCMListener(pcmListener: PCMListener?): BaseRecorder {/*...*/ } + /** + * Mute record + * 静音录制:录制进行,但是录制的声音是静音的,使用场景是用于和其他音视频进行拼接 + */ + open fun muteRecord(mute: Boolean) //设计背景音乐的url,本地的(网络的可能造成卡死) abstract fun setBackgroundMusic(url: String): BaseRecorder diff --git a/app/src/main/java/me/shetj/mp3recorder/record/activity/mix/RecordPage.kt b/app/src/main/java/me/shetj/mp3recorder/record/activity/mix/RecordPage.kt index 8929d21..6e455f4 100644 --- a/app/src/main/java/me/shetj/mp3recorder/record/activity/mix/RecordPage.kt +++ b/app/src/main/java/me/shetj/mp3recorder/record/activity/mix/RecordPage.kt @@ -108,6 +108,7 @@ open class RecordPage( musicView = view.findViewById(R.id.bg_music_view) addMusic = view.findViewById(R.id.ll_add_music) addMusic!!.setOnClickListener(this) + binding.muteAudio.setOnClickListener(this) } @@ -184,6 +185,11 @@ open class RecordPage( } } + override fun onMuteRecordChange(mute: Boolean) { + super.onMuteRecordChange(mute) + binding.muteAudio.text = if (mute) "已静音" else "开启禁音" + } + override fun onMaxChange(time: Long) { mProgressBarRecord!!.max = time.toInt() mtvAllTime!!.text = Util.formatSeconds3(time.toInt()) @@ -309,6 +315,7 @@ open class RecordPage( R.id.tv_save_record -> recordUtils!!.stopFullRecord() R.id.iv_record_state -> recordUtils!!.startOrPause(oldRecord?.audio_url ?: "") R.id.ll_add_music -> showMusicDialog() + R.id.mute_audio -> recordUtils?.muteChange() else -> { } } diff --git a/app/src/main/java/me/shetj/mp3recorder/record/adapter/RecordAdapter.kt b/app/src/main/java/me/shetj/mp3recorder/record/adapter/RecordAdapter.kt index f082bc9..bd76e01 100644 --- a/app/src/main/java/me/shetj/mp3recorder/record/adapter/RecordAdapter.kt +++ b/app/src/main/java/me/shetj/mp3recorder/record/adapter/RecordAdapter.kt @@ -6,6 +6,8 @@ import android.widget.ImageView import android.widget.SeekBar import com.chad.library.adapter.base.BaseQuickAdapter import com.chad.library.adapter.base.viewholder.BaseViewHolder +import me.shetj.base.ktx.convertToTime +import me.shetj.base.tools.time.DateUtils.datePattern import me.shetj.mp3recorder.R import me.shetj.mp3recorder.record.bean.Record import me.shetj.mp3recorder.record.utils.MediaPlayerUtils @@ -36,7 +38,7 @@ class RecordAdapter(data: MutableList?) : mediaUtils.setSeekToPlay(seekBar.progress) } } - holder.setText(R.id.tv_name, item.audioName) + holder.setText(R.id.tv_name, (item.audioName)?.toLong()?.convertToTime(datePattern)) .setGone(R.id.rl_record_view2, curPosition != itemPosition) .setText(R.id.tv_time_all, Util.formatSeconds3(item.audioLength)) .setText(R.id.tv_read_time, Util.formatSeconds3(0)) @@ -47,7 +49,7 @@ class RecordAdapter(data: MutableList?) : override fun convert(holder: BaseViewHolder, item: Record, payloads: List) { val itemPosition = holder.layoutPosition - headerLayoutCount super.convert(holder, item, payloads) - holder.setText(R.id.tv_name, item.audioName) + holder.setText(R.id.tv_name, (item.audioName)?.toLong()?.convertToTime(datePattern)) .setGone(R.id.rl_record_view2, curPosition != itemPosition) } diff --git a/app/src/main/java/me/shetj/mp3recorder/record/utils/RecordUtils.kt b/app/src/main/java/me/shetj/mp3recorder/record/utils/RecordUtils.kt index 574f995..ce20332 100644 --- a/app/src/main/java/me/shetj/mp3recorder/record/utils/RecordUtils.kt +++ b/app/src/main/java/me/shetj/mp3recorder/record/utils/RecordUtils.kt @@ -152,7 +152,7 @@ class RecordUtils( audioChannel = 1 mp3BitRate = 128 mp3Quality = 5 - enableAudioEffect = false + enableAudioEffect = true recordListener = this@RecordUtils permissionListener = this@RecordUtils pcmListener = this@RecordUtils @@ -161,7 +161,6 @@ class RecordUtils( BaseRecorder.RecorderType.MIX -> it.buildMix(Utils.app) .also { it.isEnableVBR(false) // 请不要使用,虽然可以正常播放,但是会时间错误获取会错误,暂时没有解决方法 - it.setFilter(3000, 200) } BaseRecorder.RecorderType.SIM -> it.buildSim(Utils.app) @@ -194,6 +193,10 @@ class RecordUtils( } } + private fun mute(mute:Boolean){ + mRecorder?.muteRecord(mute) + } + fun setBackgroundPlayerListener(listener: PlayerListener) { this.listener = listener mRecorder?.setBackgroundMusicListener(listener) @@ -288,6 +291,11 @@ class RecordUtils( callBack?.onError(e) } + override fun onMuteRecordChange(mute: Boolean) { + super.onMuteRecordChange(mute) + callBack?.onMuteRecordChange(mute) + } + fun setVolume(volume: Float) { mRecorder?.setBGMVolume(volume) } @@ -302,12 +310,13 @@ class RecordUtils( } override fun onBeforePCMToMp3(pcm: ShortArray): ShortArray { - val pcmdb = calculateRealVolume(pcm, pcm.size) - "修改PCM前DB:$pcmdb".logD("onBeforePCMToMp3") - val adjustVoice = BytesTransUtil.adjustVoice(pcm, 3) - val afterdb = calculateRealVolume(adjustVoice, adjustVoice.size) - "修改PCM后DB:$afterdb".logD("onBeforePCMToMp3") - return adjustVoice + // 处理完成后导致了噪音 +// val pcmdb = calculateRealVolume(pcm, pcm.size) +// "修改PCM前DB:$pcmdb".logD("onBeforePCMToMp3") +// val adjustVoice = BytesTransUtil.adjustVoice(pcm, 3) +// val afterdb = calculateRealVolume(adjustVoice, adjustVoice.size) +// "修改PCM后DB:$afterdb".logD("onBeforePCMToMp3") + return pcm } @@ -328,4 +337,12 @@ class RecordUtils( } return mVolume } + + fun muteChange() { + if (mRecorder?.mute == true){ + mute(false) + }else{ + mute(true) + } + } } diff --git a/app/src/main/res/layout/page_record_mix.xml b/app/src/main/res/layout/page_record_mix.xml index 7cb37f7..29381f1 100644 --- a/app/src/main/res/layout/page_record_mix.xml +++ b/app/src/main/res/layout/page_record_mix.xml @@ -116,6 +116,16 @@ android:visibility="gone"> + + @createTime: 2023/3/22
*/ abstract class BaseEncodeThread( - file: File, bufferSize: Int, var isContinue: Boolean, protected val isEnableVBR:Boolean, name: String + file: File, bufferSize: Int, var isContinue: Boolean, protected val isEnableVBR: Boolean, name: String ) : HandlerThread(name), AudioRecord.OnRecordPositionUpdateListener { protected var path: String protected var mFileOutputStream: FileOutputStream? protected val mMp3Buffer: ByteArray protected var needUpdate = false protected var mPCMListener: PCMListener? = null + init { this.mFileOutputStream = FileOutputStream(file, isContinue) path = file.absolutePath - if(isEnableVBR){ + if (isEnableVBR) { LameUtils.writeVBRHeader(path) } mMp3Buffer = ByteArray((7200 + bufferSize.toDouble() * 2.0 * 1.25).toInt()) @@ -81,16 +82,16 @@ abstract class BaseEncodeThread( processData() } - open fun beforePCMtoMP3(pcm:ShortArray): ShortArray { + open fun beforePCMtoMP3(pcm: ShortArray): ShortArray { if (mPCMListener == null) return pcm - return mPCMListener!!.onBeforePCMToMp3(pcm) + return mPCMListener!!.onBeforePCMToMp3(pcm) } - abstract fun addTask(rawData: ByteArray, wax: Float, bgData: ByteArray?, bgWax: Float) + abstract fun addTask(rawData: ByteArray, wax: Float, bgData: ByteArray?, bgWax: Float, mute: Boolean) - abstract fun addTask(rawData: ShortArray, readSize: Int) + abstract fun addTask(rawData: ShortArray, readSize: Int, mute: Boolean) open fun sendStopMessage() { mHandler?.sendEmptyMessage(PROCESS_STOP) diff --git a/recorder-core/src/main/java/me/shetj/recorder/core/BaseRecorder.kt b/recorder-core/src/main/java/me/shetj/recorder/core/BaseRecorder.kt index 61affd3..545663d 100644 --- a/recorder-core/src/main/java/me/shetj/recorder/core/BaseRecorder.kt +++ b/recorder-core/src/main/java/me/shetj/recorder/core/BaseRecorder.kt @@ -1,4 +1,3 @@ - package me.shetj.recorder.core import android.content.Context @@ -101,6 +100,7 @@ abstract class BaseRecorder { protected var mEncodeThread: BaseEncodeThread? = null protected var mAudioRecord: AudioRecord? = null + //region 系统自带的去噪音,增强以及回音问题 private var mNoiseSuppressor: NoiseSuppressor? = null private var mAcousticEchoCanceler: AcousticEchoCanceler? = null @@ -109,7 +109,7 @@ abstract class BaseRecorder { /** * 是否支持系统自带的去噪音,增强以及回音问题,需要自行判断 */ - private var mEnableAudioEffect:Boolean = false + private var mEnableAudioEffect: Boolean = true //endregion 系统自带的去噪音,增强以及回音问题 /** @@ -167,6 +167,12 @@ abstract class BaseRecorder { */ protected var bgLevel: Float = 0.3f + /** + * Mute 录制,但是录制的声音是静音的,使用场景是用于和其他音视频进行拼接 + */ + var mute: Boolean = false + protected set + /** * 录音Recorder 是否在活动,暂停的时候 isActive 还是true,只有录音结束了才会为false */ @@ -209,18 +215,21 @@ abstract class BaseRecorder { } } } + HANDLER_START -> { logInfo("started: mDuration = $duration , mRemindTime = $mRemindTime") if (mRecordListener != null) { mRecordListener!!.onStart() } } + HANDLER_RESUME -> { logInfo("resume: mDuration = $duration") if (mRecordListener != null) { mRecordListener!!.onResume() } } + HANDLER_COMPLETE -> { logInfo("complete: mDuration = $duration") if (mRecordListener != null && mRecordFile != null) { @@ -228,6 +237,7 @@ abstract class BaseRecorder { duration = 0 } } + HANDLER_AUTO_COMPLETE -> { logInfo("auto complete: mDuration = $duration") if (mRecordListener != null && mRecordFile != null) { @@ -235,6 +245,7 @@ abstract class BaseRecorder { duration = 0 } } + HANDLER_ERROR -> { logInfo("error : mDuration = $duration") if (mRecordListener != null) { @@ -249,27 +260,36 @@ abstract class BaseRecorder { } } } + HANDLER_PAUSE -> { logInfo("pause: mDuration = $duration") if (mRecordListener != null) { mRecordListener!!.onPause() } } + HANDLER_PERMISSION -> { logInfo("permission:record fail ,maybe need permission") if (mPermissionListener != null) { mPermissionListener!!.needPermission() } } + HANDLER_RESET -> { logInfo("reset:") if (mRecordListener != null) { mRecordListener!!.onReset() } } + HANDLER_MAX_TIME -> if (mRecordListener != null) { mRecordListener!!.onMaxChange(mMaxTime) } + + HANDLER_MUTE_RECORD -> { + mRecordListener?.onMuteRecordChange(mute) + } + else -> { } } @@ -330,7 +350,7 @@ abstract class BaseRecorder { * * @param enable */ - open fun enableAudioEffect(enable: Boolean): BaseRecorder{ + open fun enableAudioEffect(enable: Boolean): BaseRecorder { this.mEnableAudioEffect = enable return this } @@ -352,7 +372,7 @@ abstract class BaseRecorder { /** * 设置pcmListener */ - open fun setPCMListener(pcmListener: PCMListener?):BaseRecorder{ + open fun setPCMListener(pcmListener: PCMListener?): BaseRecorder { this.mPCMListener = pcmListener mEncodeThread?.setPCMListener(mPCMListener) return this @@ -452,7 +472,7 @@ abstract class BaseRecorder { * @param duration * @return */ - open fun setCurDuration(duration:Long): BaseRecorder { + open fun setCurDuration(duration: Long): BaseRecorder { this.duration = duration return this } @@ -486,6 +506,17 @@ abstract class BaseRecorder { return this } + /** + * Mute record + * 静音录制:录制进行,但是录制的声音是静音的,使用场景是用于和其他音视频进行拼接 + */ + open fun muteRecord(mute: Boolean) { + if (this.mute != mute) { + this.mute = mute + handler.sendEmptyMessage(HANDLER_MUTE_RECORD) + } + } + /** 设置背景声音大小 */ @@ -514,7 +545,8 @@ abstract class BaseRecorder { /** 替换后续录音的输出文件路径 */ - abstract fun updateDataEncode(outputFilePath: String,isContinue: Boolean) + abstract fun updateDataEncode(outputFilePath: String, isContinue: Boolean) + /** 暂停录音 */ @@ -546,15 +578,34 @@ abstract class BaseRecorder { abstract fun resumeMusic() /**重置*/ - abstract fun reset() + open fun reset(){ + isActive = false + isPause = false + isRemind = true + state = RecordState.STOPPED + duration = 0L + mRecordFile = null + handler.sendEmptyMessage(HANDLER_RESET) + } /**结束释放*/ - abstract fun destroy() + open fun destroy(){ + isActive = false + isPause = false + mRecordFile = null + isRemind = true + state = RecordState.STOPPED + releaseAEC() + handler.removeCallbacksAndMessages(null) + volumeConfig?.unregisterReceiver() + } //endregion public method open fun enableForceWriteMixBg(enable: Boolean) { - Log.e("BaseRecorder", "enableForceWriteMixBg: 该方法,需要使用MixRecorder,否则无效," + - "用于强制把背景音乐写入到录音,放在部分机型把播放的背景应用进行了移除") + Log.e( + "BaseRecorder", "enableForceWriteMixBg: 该方法,需要使用MixRecorder,否则无效," + + "用于强制把背景音乐写入到录音,放在部分机型把播放的背景应用进行了移除" + ) } /** @@ -599,6 +650,20 @@ abstract class BaseRecorder { } } + /** + * 把声音全部置空 + */ + protected fun muteAudioBuffer(buffer: ByteArray){ + buffer.fill(0) + } + + /** + * 把声音全部置空 + */ + protected fun muteAudioBuffer(buffer: ShortArray){ + buffer.fill(0) + } + protected fun calculateRealVolume(buffer: ByteArray) { val shorts = BytesTransUtil.bytes2Shorts(buffer) val readSize = shorts.size @@ -623,7 +688,7 @@ abstract class BaseRecorder { * 3. 自动增益控制 */ protected fun initAudioEffect(mAudioSessionId: Int) { - if (!mEnableAudioEffect){ + if (!mEnableAudioEffect) { releaseAEC() return } @@ -721,6 +786,7 @@ abstract class BaseRecorder { const val HANDLER_RESET = HANDLER_PAUSE + 1 // 重置 const val HANDLER_PERMISSION = HANDLER_RESET + 1 // 需要权限 const val HANDLER_MAX_TIME = HANDLER_PERMISSION + 1 // 设置了最大时间 + const val HANDLER_MUTE_RECORD = HANDLER_MAX_TIME + 1 // 切换禁音录制 const val FRAME_COUNT = 160 val DEFAULT_AUDIO_FORMAT = PCMFormat.PCM_16BIT const val TAG = "Recorder" diff --git a/recorder-core/src/main/java/me/shetj/recorder/core/RecordListener.kt b/recorder-core/src/main/java/me/shetj/recorder/core/RecordListener.kt index ec7e02d..fa65422 100644 --- a/recorder-core/src/main/java/me/shetj/recorder/core/RecordListener.kt +++ b/recorder-core/src/main/java/me/shetj/recorder/core/RecordListener.kt @@ -57,4 +57,8 @@ interface RecordListener { * 计算时间错误时 */ fun onError(e: Exception) + + fun onMuteRecordChange(mute:Boolean){ + + } } diff --git a/recorder-core/src/main/java/me/shetj/recorder/core/SimRecordListener.kt b/recorder-core/src/main/java/me/shetj/recorder/core/SimRecordListener.kt index 726b6e1..0accf04 100644 --- a/recorder-core/src/main/java/me/shetj/recorder/core/SimRecordListener.kt +++ b/recorder-core/src/main/java/me/shetj/recorder/core/SimRecordListener.kt @@ -37,4 +37,7 @@ open class SimRecordListener : RecordListener, PermissionListener,PCMListener { override fun onError(e: Exception) { } + + override fun onMuteRecordChange(mute: Boolean) { + } } diff --git a/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/MixEncodeThread.kt b/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/MixEncodeThread.kt index e39f2b7..d63140c 100644 --- a/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/MixEncodeThread.kt +++ b/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/MixEncodeThread.kt @@ -18,8 +18,8 @@ import me.shetj.recorder.core.BaseEncodeThread */ internal class MixEncodeThread @Throws(FileNotFoundException::class) -constructor(file: File, bufferSize: Int, isContinue: Boolean,private val is2CHANNEL: Boolean,isEnableVBR: Boolean) : - BaseEncodeThread(file, bufferSize, isContinue, isEnableVBR,"MixEncodeThread") { +constructor(file: File, bufferSize: Int, isContinue: Boolean, private val is2CHANNEL: Boolean, isEnableVBR: Boolean) : + BaseEncodeThread(file, bufferSize, isContinue, isEnableVBR, "MixEncodeThread") { private val mTasks = Collections.synchronizedList(ArrayList()) private val mOldTasks = Collections.synchronizedList(ArrayList()) @@ -136,10 +136,10 @@ constructor(file: File, bufferSize: Int, isContinue: Boolean,private val is2CHAN mOldTasks.add(task) } - override fun addTask(rawData: ByteArray, wax: Float, bgData: ByteArray?, bgWax: Float) { - mTasks.add(ReadMixTask(rawData.clone(), wax, bgData, bgWax)) + override fun addTask(rawData: ByteArray, wax: Float, bgData: ByteArray?, bgWax: Float, mute: Boolean) { + mTasks.add(ReadMixTask(rawData.clone(), wax, bgData, bgWax, mute)) } - override fun addTask(rawData: ShortArray, readSize: Int) { + override fun addTask(rawData: ShortArray, readSize: Int, mute: Boolean) { } } diff --git a/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/MixRecorder.kt b/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/MixRecorder.kt index 9f926ee..ced8250 100644 --- a/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/MixRecorder.kt +++ b/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/MixRecorder.kt @@ -249,9 +249,7 @@ internal class MixRecorder : BaseRecorder { val readTime = 1000.0 * readCode.toDouble() / bytesPerSecond // 计算时间长度,同时判断是否达到最大录制时间 if (onRecording(readTime)) { - mEncodeThread!!.addTask( - buffer, 1f, mPlayBackMusic!!.getBackGroundBytes(), volumeConfig?.currVolumeF ?: bgLevel - ) + mEncodeThread!!.addTask(buffer, 1f, mPlayBackMusic!!.getBackGroundBytes(), volumeConfig?.currVolumeF ?: bgLevel, mute) calculateRealVolume(buffer) } } else { @@ -363,26 +361,13 @@ internal class MixRecorder : BaseRecorder { * 重置 */ override fun reset() { - isActive = false - isPause = false - isRemind = true - state = RecordState.STOPPED - duration = 0L - mRecordFile = null - handler.sendEmptyMessage(HANDLER_RESET) + super.reset() backgroundMusicIsPlay = !bgPlayer.isIsPause bgPlayer.release() } override fun destroy() { - isActive = false - isPause = false - mRecordFile = null - isRemind = true - bgPlayer.release() - releaseAEC() - handler.removeCallbacksAndMessages(null) - volumeConfig?.unregisterReceiver() + super.destroy() plugConfigs?.unregisterReceiver() } //endregion 公开方法! diff --git a/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/ReadMixTask.kt b/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/ReadMixTask.kt index afba877..7eec962 100644 --- a/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/ReadMixTask.kt +++ b/recorder-mix/src/main/java/me/shetj/recorder/mixRecorder/ReadMixTask.kt @@ -9,10 +9,15 @@ internal class ReadMixTask( private val rawData: ByteArray, // 录制的人声音 private val wax: Float, // 人声音增强 private val bgData: ByteArray?, // 录制的背景音乐 可能没有 - private val bgWax: Float // 背景声音降低 + private val bgWax: Float, // 背景声音降低, + private val mute:Boolean = false, ) { fun getData(): ShortArray { + if (mute){ + rawData.fill(0) + return BytesTransUtil.bytes2Shorts(rawData) + } val mixBuffer = mixBuffer(rawData, bgData) ?: return BytesTransUtil.bytes2Shorts( BytesTransUtil.changeDataWithVolume(rawData, wax) ) diff --git a/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/DataEncodeThread.kt b/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/DataEncodeThread.kt index ec5727b..b697cd6 100644 --- a/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/DataEncodeThread.kt +++ b/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/DataEncodeThread.kt @@ -38,7 +38,7 @@ constructor( if (mTasks.size > 0) { val task = mTasks.removeAt(0) addOldData(task) - val buffer = beforePCMtoMP3(task.data) + val buffer = beforePCMtoMP3(task.getData()) val encodedSize: Int val readSize: Int if (is2CHANNEL) { @@ -105,7 +105,7 @@ constructor( private fun setOldDateToFile(): Int { if (mOldTasks.size > 0 && mFileOutputStream != null) { val task = mOldTasks.removeAt(0) - val buffer = beforePCMtoMP3(task.data) + val buffer = beforePCMtoMP3(task.getData()) val encodedSize: Int val readSize: Int if (is2CHANNEL) { @@ -135,11 +135,11 @@ constructor( mOldTasks.add(task) } - override fun addTask(rawData: ByteArray, wax: Float, bgData: ByteArray?, bgWax: Float) { + override fun addTask(rawData: ByteArray, wax: Float, bgData: ByteArray?, bgWax: Float,mute:Boolean) { } - override fun addTask(rawData: ShortArray, readSize: Int) { - mTasks.add(ReadTask(rawData, readSize)) + override fun addTask(rawData: ShortArray, readSize: Int,mute:Boolean) { + mTasks.add(ReadTask(rawData.clone(), readSize,mute)) } } diff --git a/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/ReadTask.kt b/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/ReadTask.kt index 9556da0..06c29d6 100644 --- a/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/ReadTask.kt +++ b/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/ReadTask.kt @@ -1,6 +1,13 @@ package me.shetj.recorder.simRecorder -internal class ReadTask(rawData: ShortArray, val readSize: Int) { - val data: ShortArray = rawData.clone() + +internal class ReadTask(private val data: ShortArray, val readSize: Int, private val mute:Boolean) { + + fun getData():ShortArray{ + if (mute){ + data.fill(0) + } + return data + } } diff --git a/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/SimRecorder.kt b/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/SimRecorder.kt index 4f5bd9b..46969e5 100644 --- a/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/SimRecorder.kt +++ b/recorder-sim/src/main/java/me/shetj/recorder/simRecorder/SimRecorder.kt @@ -1,4 +1,3 @@ - package me.shetj.recorder.simRecorder import android.content.Context @@ -92,10 +91,12 @@ internal class SimRecorder : BaseRecorder { 1 -> { AudioFormat.CHANNEL_IN_MONO } + 2 -> { AudioFormat.CHANNEL_IN_STEREO } - else -> AudioFormat.CHANNEL_IN_STEREO + + else -> AudioFormat.CHANNEL_IN_STEREO } this.is2Channel = mLameInChannel == 2 releaseAEC() @@ -112,10 +113,12 @@ internal class SimRecorder : BaseRecorder { 1 -> { AudioFormat.CHANNEL_IN_MONO } + 2 -> { AudioFormat.CHANNEL_IN_STEREO } - else -> AudioFormat.CHANNEL_IN_STEREO + + else -> AudioFormat.CHANNEL_IN_STEREO } return true } @@ -129,7 +132,7 @@ internal class SimRecorder : BaseRecorder { return false } - override fun updateDataEncode(outputFilePath: String,isContinue: Boolean ) { + override fun updateDataEncode(outputFilePath: String, isContinue: Boolean) { setOutputFile(outputFilePath, isContinue) mEncodeThread?.isContinue = isContinue mEncodeThread?.update(outputFilePath) @@ -152,7 +155,7 @@ internal class SimRecorder : BaseRecorder { try { initAudioRecorder() mAudioRecord!!.startRecording() - }catch (ex:IllegalStateException){ + } catch (ex: IllegalStateException) { handler.sendEmptyMessage(HANDLER_PERMISSION) ex.printStackTrace() return @@ -190,7 +193,7 @@ internal class SimRecorder : BaseRecorder { * x2 转成字节做时间计算 */ val readTime = 1000.0 * readSize.toDouble() * 2 / bytesPerSecond - mEncodeThread!!.addTask(mPCMBuffer!!, readSize) + mEncodeThread!!.addTask(mPCMBuffer!!, readSize, mute) calculateRealVolume(mPCMBuffer!!, readSize) // short 是2个字节 byte 是1个字节8位 onRecording(readTime) @@ -319,26 +322,11 @@ internal class SimRecorder : BaseRecorder { } override fun reset() { - isActive = false - isPause = false - state = RecordState.STOPPED - duration = 0L - mRecordFile = null + super.reset() backgroundMusicIsPlay = bgPlayer.isPlaying - handler.sendEmptyMessage(HANDLER_RESET) bgPlayer.stopPlay() } - override fun destroy() { - isActive = false - isPause = false - state = RecordState.STOPPED - mRecordFile = null - releaseAEC() - bgPlayer.stopPlay() - handler.removeCallbacksAndMessages(null) - volumeConfig?.unregisterReceiver() - } override fun startPlayMusic() { if (!bgPlayer.isPlaying) { @@ -422,7 +410,7 @@ internal class SimRecorder : BaseRecorder { mRecordFile!!, mBufferSize, isContinue, - mChannelConfig == AudioFormat.CHANNEL_IN_STEREO,openVBR + mChannelConfig == AudioFormat.CHANNEL_IN_STEREO, openVBR ) mEncodeThread!!.start() mEncodeThread!!.setPCMListener(mPCMListener) diff --git a/recorder-st/src/main/java/me/shetj/recorder/soundtouch/DataSTEncodeThread.kt b/recorder-st/src/main/java/me/shetj/recorder/soundtouch/DataSTEncodeThread.kt index ee2ef21..a998151 100644 --- a/recorder-st/src/main/java/me/shetj/recorder/soundtouch/DataSTEncodeThread.kt +++ b/recorder-st/src/main/java/me/shetj/recorder/soundtouch/DataSTEncodeThread.kt @@ -1,4 +1,3 @@ - package me.shetj.recorder.soundtouch import java.io.File @@ -22,9 +21,9 @@ constructor( isContinue: Boolean, private val is2CHANNEL: Boolean, private val soundTouchKit: SoundTouchKit, - isEnableVBR:Boolean + isEnableVBR: Boolean ) : - BaseEncodeThread(file, bufferSize, isContinue, isEnableVBR,"DataSTEncodeThread") { + BaseEncodeThread(file, bufferSize, isContinue, isEnableVBR, "DataSTEncodeThread") { private val mSTBuffer = ShortArray(7200 + (bufferSize.toDouble() * 2.0).toInt()) // 处理变音的后的数据 private val mTasks = Collections.synchronizedList(ArrayList()) @@ -40,7 +39,7 @@ constructor( // 处理变音,如果需要变音,仅需要得到变音后的数据,以及长度 return if (soundTouchKit.isUse()) { var processSamples: Int - soundTouchKit.putSamples(task.data, task.readSize) + soundTouchKit.putSamples(task.getData(), task.readSize) do { processSamples = soundTouchKit.receiveSamples(mSTBuffer) if (processSamples != 0) { @@ -49,7 +48,7 @@ constructor( } while (processSamples != 0) 1 } else { - processBuffer(task.data, task.readSize) + processBuffer(task.getData(), task.readSize) } } return 0 @@ -110,18 +109,18 @@ constructor( mFileOutputStream?.close() mFileOutputStream = null mFileOutputStream = FileOutputStream(path, isContinue) - if(isEnableVBR){ + if (isEnableVBR) { LameUtils.writeVBRHeader(path) } needUpdate = false } } - override fun addTask(rawData: ByteArray, wax: Float, bgData: ByteArray?, bgWax: Float) { + override fun addTask(rawData: ByteArray, wax: Float, bgData: ByteArray?, bgWax: Float, mute: Boolean) { } - override fun addTask(rawData: ShortArray, readSize: Int) { - mTasks.add(ReadTask(rawData, readSize)) + override fun addTask(rawData: ShortArray, readSize: Int, mute: Boolean) { + mTasks.add(ReadTask(rawData.clone(), readSize, mute)) } } diff --git a/recorder-st/src/main/java/me/shetj/recorder/soundtouch/ReadTask.kt b/recorder-st/src/main/java/me/shetj/recorder/soundtouch/ReadTask.kt index 26111ab..dce561d 100644 --- a/recorder-st/src/main/java/me/shetj/recorder/soundtouch/ReadTask.kt +++ b/recorder-st/src/main/java/me/shetj/recorder/soundtouch/ReadTask.kt @@ -1,6 +1,12 @@ package me.shetj.recorder.soundtouch -internal class ReadTask(rawData: ShortArray, val readSize: Int) { - val data: ShortArray = rawData.clone() +internal class ReadTask(private val data: ShortArray, val readSize: Int, private val mute:Boolean) { + + fun getData():ShortArray{ + if (mute){ + data.fill(0) + } + return data + } } diff --git a/recorder-st/src/main/java/me/shetj/recorder/soundtouch/STRecorder.kt b/recorder-st/src/main/java/me/shetj/recorder/soundtouch/STRecorder.kt index 42575be..e8d9fc5 100644 --- a/recorder-st/src/main/java/me/shetj/recorder/soundtouch/STRecorder.kt +++ b/recorder-st/src/main/java/me/shetj/recorder/soundtouch/STRecorder.kt @@ -1,4 +1,3 @@ - package me.shetj.recorder.soundtouch import android.annotation.SuppressLint @@ -76,9 +75,11 @@ internal class STRecorder : BaseRecorder { 1 -> { AudioFormat.CHANNEL_IN_MONO } + 2 -> { AudioFormat.CHANNEL_IN_STEREO } + else -> AudioFormat.CHANNEL_IN_STEREO } is2Channel = mLameInChannel == 2 @@ -101,11 +102,13 @@ internal class STRecorder : BaseRecorder { releaseAEC() 1 } + channel >= 2 -> { mChannelConfig = AudioFormat.CHANNEL_IN_STEREO releaseAEC() 2 } + else -> 2 } return true @@ -120,7 +123,7 @@ internal class STRecorder : BaseRecorder { return false } - override fun updateDataEncode(outputFilePath: String,isContinue: Boolean ) { + override fun updateDataEncode(outputFilePath: String, isContinue: Boolean) { setOutputFile(outputFilePath, isContinue) mEncodeThread?.isContinue = isContinue mEncodeThread?.update(outputFilePath) @@ -180,7 +183,7 @@ internal class STRecorder : BaseRecorder { continue } val readTime = 1000.0 * readSize.toDouble() * 2 / bytesPerSecond - mEncodeThread!!.addTask(mPCMBuffer!!, readSize) + mEncodeThread!!.addTask(mPCMBuffer!!, readSize, mute) calculateRealVolume(mPCMBuffer!!, readSize) // short 是2个字节 byte 是1个字节8位 onRecording(readTime) @@ -304,23 +307,12 @@ internal class STRecorder : BaseRecorder { * 重置 */ override fun reset() { - isActive = false - isPause = false - state = RecordState.STOPPED - duration = 0L - mRecordFile = null - handler.sendEmptyMessage(HANDLER_RESET) + super.reset() soundTouch.clean() } override fun destroy() { - isActive = false - isPause = false - state = RecordState.STOPPED - mRecordFile = null - releaseAEC() - handler.removeCallbacksAndMessages(null) - volumeConfig?.unregisterReceiver() + super.destroy() soundTouch.destroy() }