Skip to content

Commit

Permalink
Merge pull request #76 from ZTFtrue/develope
Browse files Browse the repository at this point in the history
add feature
  • Loading branch information
ZTFtrue authored Oct 16, 2024
2 parents e6d306c + 232159f commit 6f98f8e
Show file tree
Hide file tree
Showing 14 changed files with 910 additions and 63 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ android {
applicationId = "com.ztftrue.music"
minSdk = 30
targetSdk = 34
versionCode = 35
versionName = "0.1.35"
versionCode = 36
versionName = "0.1.36"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/ztftrue/music/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaControllerCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResultLauncher
Expand Down Expand Up @@ -49,6 +50,7 @@ import com.ztftrue.music.play.ACTION_PlayLIST_CHANGE
import com.ztftrue.music.play.ACTION_TRACKS_DELETE
import com.ztftrue.music.play.EVENT_MEDIA_ITEM_Change
import com.ztftrue.music.play.EVENT_SLEEP_TIME_Change
import com.ztftrue.music.play.EVENT_Visualization_Change
import com.ztftrue.music.play.PlayService
import com.ztftrue.music.sqlData.model.ARTIST_TYPE
import com.ztftrue.music.sqlData.model.GENRE_TYPE
Expand Down Expand Up @@ -451,6 +453,10 @@ class MainActivity : ComponentActivity() {
compatSplashScreen?.setKeepOnScreenCondition { musicViewModel.mainTabList.isEmpty() }
Utils.initSettingsData(musicViewModel, this)
musicViewModel.prepareArtistAndGenreCover(this@MainActivity)
musicViewModel.musicVisualizationEnable.value =
SharedPreferencesUtils.getEnableMusicVisualization(this@MainActivity)
musicViewModel.showMusicCover.value =
SharedPreferencesUtils.getShowMusicCover(this@MainActivity)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {

if (ActivityCompat.checkSelfPermission(
Expand Down Expand Up @@ -560,6 +566,11 @@ class MainActivity : ComponentActivity() {
lock.unlock()
}

// Add extension function to MediaControllerCompat.Callback
fun MediaControllerCompat.Callback.onVisualizerChangedExtension(data: FloatArray?) {
println("Handling visualizer data: $data")
}

val callback = object : MediaControllerCompat.Callback() {
override fun onPlaybackStateChanged(state: PlaybackStateCompat?) {
super.onPlaybackStateChanged(state)
Expand Down Expand Up @@ -595,6 +606,13 @@ class MainActivity : ComponentActivity() {
if (remainTime == 0L) {
musicViewModel.sleepTime.longValue = 0
}
} else if (it.getInt("type") == EVENT_Visualization_Change) {
val magnitude = it.getFloatArray("magnitude")?.toList()
if (magnitude != null) {
musicViewModel.musicVisualizationData.clear()
musicViewModel.musicVisualizationData.addAll(magnitude)
}
// Log.d("magnitude", magnitude?.size.toString())
}
}
}
Expand Down
54 changes: 34 additions & 20 deletions app/src/main/java/com/ztftrue/music/MusicViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,12 @@ class MusicViewModel : ViewModel() {
var mediaController: MediaControllerCompat? = null
var mediaBrowser: MediaBrowserCompat? = null

// val albumScrollDirection = mutableStateOf(ScrollDirectionType.GRID_VERTICAL)
// val albumScrollDirection = mutableStateOf(ScrollDirectionType.GRID_VERTICAL)
// val artistScrollDirection = mutableStateOf(ScrollDirectionType.GRID_VERTICAL)
// val genreScrollDirection = mutableStateOf(ScrollDirectionType.GRID_VERTICAL)

var musicVisualizationData = mutableStateListOf<Float>()
var musicVisualizationEnable= mutableStateOf(false)
var showMusicCover= mutableStateOf(false)
// 当前播放的列表,应该换数据结构存储,每个列表设置变量 播放状态,album和 genres 也是,艺术家跳转到 album, 然后在下一步处理
// 每次播放仅设置当前列表的状态

Expand Down Expand Up @@ -199,8 +201,14 @@ class MusicViewModel : ViewModel() {
val fileLyrics = arrayListOf<ListStringCaption>()
tags.clear()
// if embedded lyrics is prior, first import lyrics
if(firstEmbeddedLyrics) {
embeddedLyrics.addAll(CaptionUtils.getEmbeddedLyrics(currentPlay.path, context, tags))
if (firstEmbeddedLyrics) {
embeddedLyrics.addAll(
CaptionUtils.getEmbeddedLyrics(
currentPlay.path,
context,
tags
)
)
}
if (embeddedLyrics.isNotEmpty()) {
lyricsType = LyricsType.TEXT
Expand All @@ -219,22 +227,22 @@ class MusicViewModel : ViewModel() {
}
// Same as tracks file
if (fileLyrics.isEmpty()) {
val fileR = Utils.checkLyrics(
currentPlay.path.substring(
0,
currentPlay.path.lastIndexOf("."),
)
val fileR = Utils.checkLyrics(
currentPlay.path.substring(
0,
currentPlay.path.lastIndexOf("."),
)
if (fileR != null) {
lyricsType = fileR.type
fileLyrics.addAll(
readCaptions(
File(fileR.path).bufferedReader(),
fileR.type,
context
)
)
if (fileR != null) {
lyricsType = fileR.type
fileLyrics.addAll(
readCaptions(
File(fileR.path).bufferedReader(),
fileR.type,
context
)
}
)
}
}
if (fileLyrics.isEmpty()) {
val musicName: String = try {
Expand Down Expand Up @@ -313,8 +321,14 @@ class MusicViewModel : ViewModel() {
}
}
}
if(fileLyrics.isEmpty()&&!firstEmbeddedLyrics) {
embeddedLyrics.addAll(CaptionUtils.getEmbeddedLyrics(currentPlay.path, context, tags))
if (fileLyrics.isEmpty() && !firstEmbeddedLyrics) {
embeddedLyrics.addAll(
CaptionUtils.getEmbeddedLyrics(
currentPlay.path,
context,
tags
)
)
}
if (fileLyrics.isNotEmpty()) {
isEmbeddedLyrics.value = false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ztftrue.music.effects

import android.util.Log
import androidx.media3.common.C
import androidx.media3.common.audio.AudioProcessor
import androidx.media3.common.audio.AudioProcessor.EMPTY_BUFFER
Expand Down Expand Up @@ -29,7 +30,7 @@ class EchoAudioProcessor : AudioProcessor {

private val framesInBuffer = 4096
private var bufferSize = 0
private val dataBuffer: ByteBuffer
private var dataBuffer: ByteBuffer
private lateinit var converter: TarsosDSPAudioFloatConverter
private var delayTime = 0.5f
private var decay = 1.0f
Expand Down Expand Up @@ -98,9 +99,21 @@ class EchoAudioProcessor : AudioProcessor {
return
}
inputBuffer.order(ByteOrder.nativeOrder())
if (dataBuffer.remaining() < 1 || dataBuffer.remaining() < inputBuffer.limit()) {
expandBuffer(dataBuffer.capacity() + inputBuffer.limit() * 2);
Log.d("ExpandBuffer", dataBuffer.remaining().toString())
}

dataBuffer.put(inputBuffer)
}

private fun expandBuffer(newCapacity: Int) {
val newBuffer = ByteBuffer.allocate(newCapacity)
dataBuffer.flip() // 切换到读取模式
newBuffer.put(dataBuffer) // 复制内容
dataBuffer = newBuffer // 替换旧的 ByteBuffer
}

override fun getOutput(): ByteBuffer {
processData()
val outputBuffer: ByteBuffer = this.outputBuffer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.ztftrue.music.effects

import android.util.Log
import androidx.media3.common.C
import androidx.media3.common.audio.AudioProcessor
import androidx.media3.common.audio.AudioProcessor.EMPTY_BUFFER
import androidx.media3.common.util.UnstableApi
import be.tarsos.dsp.io.TarsosDSPAudioFloatConverter
import be.tarsos.dsp.io.TarsosDSPAudioFormat
import com.ztftrue.music.effects.SoundUtils.getBytePerSample
import com.ztftrue.music.effects.SoundUtils.getOutputSize
import com.ztftrue.music.utils.Utils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
Expand All @@ -31,7 +34,7 @@ class EqualizerAudioProcessor : AudioProcessor {
private var sampleBufferRealLeft: DoubleArray = DoubleArray(0)
private var sampleBufferRealRight: DoubleArray = DoubleArray(0)

private var bufferSize = 2048
private var bufferSize = 512
private var outputBuffer: ByteBuffer = EMPTY_BUFFER
private var dataBuffer: ByteBuffer = EMPTY_BUFFER
private var inputEnded = false
Expand Down Expand Up @@ -81,7 +84,10 @@ class EqualizerAudioProcessor : AudioProcessor {
outputAudioFormat = inputAudioFormat
// ENCODING_PCM_16BIT, is two byte to one float
r = if (outputAudioFormat!!.encoding == C.ENCODING_PCM_16BIT) 2 else 1
dataBuffer = ByteBuffer.allocate(bufferSize * 16)

BYTES_PER_SAMPLE = getBytePerSample(outputAudioFormat!!.encoding)
bufferSize = getOutputSize(outputAudioFormat!!, BYTES_PER_SAMPLE)
dataBuffer = ByteBuffer.allocate(bufferSize * 8)
val size = bufferSize / r / outputAudioFormat!!.channelCount
sampleBufferRealLeft = DoubleArray(size)
sampleBufferRealRight = DoubleArray(size)
Expand Down Expand Up @@ -109,7 +115,10 @@ class EqualizerAudioProcessor : AudioProcessor {
return outputAudioFormat!!

}
var BYTES_PER_SAMPLE: Int = 2

private var leftMax = 1.0
private var rightMax = 1.0
override fun isActive(): Boolean {
return outputAudioFormat != AudioProcessor.AudioFormat.NOT_SET
}
Expand All @@ -122,10 +131,19 @@ class EqualizerAudioProcessor : AudioProcessor {
if (!inputBuffer.hasRemaining()) {
return
}
if (dataBuffer.remaining() < 1||dataBuffer.remaining() < inputBuffer.limit()) {
expandBuffer(dataBuffer.capacity()+inputBuffer.limit() * 2)
Log.d("ExpandBuffer", dataBuffer.remaining().toString())
}
dataBuffer.put(inputBuffer)
}


private fun expandBuffer(newCapacity: Int) {
val newBuffer = ByteBuffer.allocate(newCapacity)
dataBuffer.flip() // 切换到读取模式
newBuffer.put(dataBuffer) // 复制内容
dataBuffer = newBuffer // 替换旧的 ByteBuffer
}
override fun queueEndOfStream() {
// TODO
dataBuffer.flip()
Expand All @@ -136,13 +154,7 @@ class EqualizerAudioProcessor : AudioProcessor {
inputEnded = true
}

val BYTES_PER_SAMPLE: Int = 2

private var leftMax = 1.0
private var rightMax = 1.0
fun getOutputSize(): Int {
return outputAudioFormat!!.sampleRate * outputAudioFormat!!.channelCount * BYTES_PER_SAMPLE
}

private var changeDb = false
override fun getOutput(): ByteBuffer {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.ztftrue.music.effects

import be.tarsos.dsp.util.fft.FFT


class PCMToFrequencyDomain(private val bufferSize: Int, private val sampleRate: Float) {
private val fft: FFT = FFT(bufferSize)
val fftSize: Int = bufferSize / 2
fun process(pcmData: FloatArray): FloatArray {
val paddedData = pcmData.copyOf(bufferSize)
fft.forwardTransform(paddedData)
// Retrieve magnitudes
val amplitudes = FloatArray(fftSize)
fft.modulus(paddedData, amplitudes)
// Optionally: Print frequencies and magnitudes
// val r=FloatArray(fftSize)
// for (i in amplitudes.indices) {
// val frequency = fft.binToHz(i, sampleRate) // assuming 44100 Hz sample rate
// r[i] = amplitudes[i]
//// println("Frequency: %.2f Hz, Magnitude: %.2f".format(frequency, amplitudes[i]))
// }
// Log.d("amplitudes", r.contentToString())
return amplitudes
}

}
Loading

0 comments on commit 6f98f8e

Please sign in to comment.