-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
38 changed files
with
1,376 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
app/src/main/java/dev/arkbuilders/arkmemo/di/MediaModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package dev.arkbuilders.arkmemo.di | ||
|
||
import dagger.Binds | ||
import dagger.Module | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.components.SingletonComponent | ||
import dev.arkbuilders.arkmemo.media.ArkMediaPlayer | ||
import dev.arkbuilders.arkmemo.media.ArkMediaPlayerImpl | ||
import dev.arkbuilders.arkmemo.media.ArkAudioRecorder | ||
import dev.arkbuilders.arkmemo.media.ArkAudioRecorderImpl | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
abstract class MediaModule { | ||
|
||
@Binds | ||
abstract fun bindArkAudioRecorder(impl: ArkAudioRecorderImpl): ArkAudioRecorder | ||
|
||
@Binds | ||
abstract fun bindArkMediaPlayer(impl: ArkMediaPlayerImpl): ArkMediaPlayer | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
app/src/main/java/dev/arkbuilders/arkmemo/media/ArkAudioRecorder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package dev.arkbuilders.arkmemo.media | ||
|
||
import java.nio.file.Path | ||
|
||
interface ArkAudioRecorder { | ||
|
||
fun init() | ||
|
||
fun start() | ||
|
||
fun pause() | ||
|
||
fun stop() | ||
|
||
fun resume() | ||
|
||
fun reset() | ||
|
||
fun maxAmplitude(): Int | ||
|
||
fun getRecording(): Path | ||
} |
59 changes: 59 additions & 0 deletions
59
app/src/main/java/dev/arkbuilders/arkmemo/media/ArkAudioRecorderImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package dev.arkbuilders.arkmemo.media | ||
|
||
import android.content.Context | ||
import android.media.MediaRecorder | ||
import android.os.Build | ||
import dagger.hilt.android.qualifiers.ApplicationContext | ||
import java.nio.file.Path | ||
import javax.inject.Inject | ||
import kotlin.io.path.createTempFile | ||
|
||
class ArkAudioRecorderImpl @Inject constructor( | ||
@ApplicationContext private val context: Context | ||
): ArkAudioRecorder { | ||
|
||
private var recorder: MediaRecorder? = null | ||
|
||
private val tempFile = createTempFile().toFile() | ||
|
||
override fun init() { | ||
recorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) | ||
MediaRecorder(context) | ||
else MediaRecorder() | ||
recorder?.apply { | ||
setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION) | ||
setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) | ||
setOutputFile(tempFile) | ||
setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) | ||
prepare() | ||
} | ||
} | ||
|
||
override fun start() { | ||
recorder?.start() | ||
} | ||
|
||
override fun pause() { | ||
recorder?.pause() | ||
} | ||
|
||
override fun resume() { | ||
recorder?.resume() | ||
} | ||
|
||
override fun reset() { | ||
recorder?.reset() | ||
} | ||
|
||
override fun stop() { | ||
recorder?.let { | ||
it.stop() | ||
it.release() | ||
} | ||
recorder = null | ||
} | ||
|
||
override fun maxAmplitude(): Int = recorder?.maxAmplitude!! | ||
|
||
override fun getRecording(): Path = tempFile.toPath() | ||
} |
24 changes: 24 additions & 0 deletions
24
app/src/main/java/dev/arkbuilders/arkmemo/media/ArkMediaPlayer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package dev.arkbuilders.arkmemo.media | ||
|
||
import android.media.MediaPlayer | ||
|
||
interface ArkMediaPlayer: MediaPlayer.OnCompletionListener { | ||
|
||
var onCompletion: () -> Unit | ||
|
||
fun init(path: String) | ||
|
||
fun play() | ||
|
||
fun stop() | ||
|
||
fun pause() | ||
|
||
fun seekTo(point: Int) | ||
|
||
fun duration(): Int | ||
|
||
fun currentPosition(): Int | ||
|
||
fun isPlaying(): Boolean | ||
} |
48 changes: 48 additions & 0 deletions
48
app/src/main/java/dev/arkbuilders/arkmemo/media/ArkMediaPlayerImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package dev.arkbuilders.arkmemo.media | ||
|
||
import android.media.MediaPlayer | ||
import javax.inject.Inject | ||
|
||
class ArkMediaPlayerImpl @Inject constructor(): ArkMediaPlayer { | ||
|
||
private var player: MediaPlayer? = null | ||
|
||
override var onCompletion: () -> Unit = {} | ||
|
||
override fun init(path: String) { | ||
player = MediaPlayer().apply { | ||
setDataSource(path) | ||
prepare() | ||
} | ||
} | ||
|
||
override fun play() { | ||
player?.start() | ||
} | ||
|
||
override fun stop() { | ||
player?.let { | ||
it.stop() | ||
it.release() | ||
} | ||
player = null | ||
} | ||
|
||
override fun pause() { | ||
player?.pause() | ||
} | ||
|
||
override fun seekTo(point: Int) { | ||
player?.seekTo(point) | ||
} | ||
|
||
override fun duration(): Int = player?.duration!! | ||
|
||
override fun currentPosition(): Int = player?.currentPosition!! | ||
|
||
override fun isPlaying(): Boolean = player?.isPlaying!! | ||
|
||
override fun onCompletion(p0: MediaPlayer?) { | ||
onCompletion() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
app/src/main/java/dev/arkbuilders/arkmemo/models/VoiceNote.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package dev.arkbuilders.arkmemo.models | ||
|
||
import android.os.Parcelable | ||
import dev.arkbuilders.arklib.data.index.Resource | ||
import kotlinx.parcelize.IgnoredOnParcel | ||
import kotlinx.parcelize.Parcelize | ||
import java.nio.file.Path | ||
import kotlin.io.path.createTempFile | ||
|
||
@Parcelize | ||
class VoiceNote( | ||
override val title: String = "", | ||
override val description: String = "", | ||
val duration: String = "", | ||
@IgnoredOnParcel | ||
var path: Path = createTempFile(), | ||
@IgnoredOnParcel | ||
override var resource: Resource? = null | ||
): Note, Parcelable |
106 changes: 106 additions & 0 deletions
106
app/src/main/java/dev/arkbuilders/arkmemo/repo/voices/VoiceNotesRepo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package dev.arkbuilders.arkmemo.repo.voices | ||
|
||
import android.util.Log | ||
import dev.arkbuilders.arklib.computeId | ||
import dev.arkbuilders.arklib.data.index.Resource | ||
import dev.arkbuilders.arkmemo.di.IO_DISPATCHER | ||
import dev.arkbuilders.arkmemo.models.GraphicNote | ||
import dev.arkbuilders.arkmemo.models.SaveNoteResult | ||
import dev.arkbuilders.arkmemo.models.VoiceNote | ||
import dev.arkbuilders.arkmemo.preferences.MemoPreferences | ||
import dev.arkbuilders.arkmemo.repo.NotesRepo | ||
import dev.arkbuilders.arkmemo.repo.NotesRepoHelper | ||
import dev.arkbuilders.arkmemo.utils.listFiles | ||
import kotlinx.coroutines.CoroutineDispatcher | ||
import kotlinx.coroutines.withContext | ||
import java.nio.file.Path | ||
import javax.inject.Inject | ||
import javax.inject.Named | ||
import kotlin.io.path.exists | ||
import kotlin.io.path.fileSize | ||
import kotlin.io.path.createTempFile | ||
import kotlin.io.path.extension | ||
import kotlin.io.path.getLastModifiedTime | ||
import kotlin.io.path.name | ||
|
||
class VoiceNotesRepo @Inject constructor( | ||
private val memoPreferences: MemoPreferences, | ||
@Named(IO_DISPATCHER) private val iODispatcher: CoroutineDispatcher, | ||
private val helper: NotesRepoHelper | ||
): NotesRepo<VoiceNote> { | ||
|
||
private lateinit var root: Path | ||
|
||
override suspend fun init() { | ||
root = memoPreferences.getNotesStorage() | ||
helper.init() | ||
} | ||
|
||
override suspend fun read(): List<VoiceNote> = withContext(iODispatcher) { | ||
readStorage() | ||
} | ||
|
||
override suspend fun delete(note: VoiceNote) { | ||
helper.deleteNote(note) | ||
} | ||
|
||
override suspend fun save(note: VoiceNote, callback: (SaveNoteResult) -> Unit) { | ||
write(note) { callback(it) } | ||
} | ||
|
||
private suspend fun write( | ||
note: VoiceNote, | ||
callback: (SaveNoteResult) -> Unit | ||
) = withContext(iODispatcher) { | ||
val tempPath = note.path | ||
val size = tempPath.fileSize() | ||
val id = computeId(size, tempPath) | ||
|
||
Log.d(VOICES_REPO, "initial resource name is ${tempPath.name}") | ||
|
||
helper.persistNoteProperties(resourceId = id, noteTitle = note.title) | ||
|
||
val resourcePath = root.resolve("${id}.$VOICE_EXT") | ||
if (resourcePath.exists()) { | ||
Log.d( | ||
VOICES_REPO, | ||
"resource with similar content already exists" | ||
) | ||
callback(SaveNoteResult.ERROR_EXISTING) | ||
return@withContext | ||
} | ||
|
||
helper.renameResource( | ||
note, | ||
tempPath, | ||
resourcePath, | ||
id | ||
) | ||
note.path = resourcePath | ||
Log.d(VOICES_REPO, "resource renamed to $resourcePath successfully") | ||
callback(SaveNoteResult.SUCCESS) | ||
} | ||
|
||
private suspend fun readStorage(): List<VoiceNote> = withContext(iODispatcher) { | ||
root.listFiles(VOICE_EXT) { path -> | ||
val id = computeId(path.fileSize(), path) | ||
val resource = Resource( | ||
id = id, | ||
name = path.name, | ||
extension = path.extension, | ||
modified = path.getLastModifiedTime() | ||
) | ||
|
||
val userNoteProperties = helper.readProperties(id, "") | ||
VoiceNote( | ||
title = userNoteProperties.title, | ||
description = userNoteProperties.description, | ||
path = path, | ||
resource = resource | ||
) | ||
} | ||
} | ||
} | ||
|
||
private const val VOICES_REPO = "voices-repo" | ||
private const val VOICE_EXT = "3gp" |
Oops, something went wrong.