@siteed/expo-audio-stream 2.0.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +46 -27
  2. package/build/index.d.ts +11 -12
  3. package/build/index.js +44 -10
  4. package/package.json +49 -110
  5. package/src/index.ts +18 -33
  6. package/CHANGELOG.md +0 -195
  7. package/android/build.gradle +0 -105
  8. package/android/src/main/AndroidManifest.xml +0 -27
  9. package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +0 -166
  10. package/android/src/main/java/net/siteed/audiostream/AudioDataEncoder.kt +0 -9
  11. package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +0 -131
  12. package/android/src/main/java/net/siteed/audiostream/AudioFormatUtils.kt +0 -103
  13. package/android/src/main/java/net/siteed/audiostream/AudioNotificationsManager.kt +0 -435
  14. package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +0 -1936
  15. package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +0 -1437
  16. package/android/src/main/java/net/siteed/audiostream/AudioRecordingService.kt +0 -138
  17. package/android/src/main/java/net/siteed/audiostream/Constants.kt +0 -20
  18. package/android/src/main/java/net/siteed/audiostream/EventSender.kt +0 -7
  19. package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +0 -509
  20. package/android/src/main/java/net/siteed/audiostream/FFT.kt +0 -99
  21. package/android/src/main/java/net/siteed/audiostream/Features.kt +0 -98
  22. package/android/src/main/java/net/siteed/audiostream/NotificationConfig.kt +0 -70
  23. package/android/src/main/java/net/siteed/audiostream/PermissionUtils.kt +0 -59
  24. package/android/src/main/java/net/siteed/audiostream/RecordingActionReceiver.kt +0 -59
  25. package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +0 -205
  26. package/android/src/main/java/net/siteed/audiostream/WaveformConfig.kt +0 -19
  27. package/android/src/main/java/net/siteed/audiostream/WaveformRenderer.kt +0 -159
  28. package/android/src/main/res/drawable/ic_default_action_icon.xml +0 -16
  29. package/android/src/main/res/drawable/ic_microphone.xml +0 -13
  30. package/android/src/main/res/drawable/ic_pause.xml +0 -10
  31. package/android/src/main/res/drawable/ic_play.xml +0 -10
  32. package/android/src/main/res/drawable/ic_stop.xml +0 -10
  33. package/android/src/main/res/layout/notification_recording.xml +0 -37
  34. package/android/src/main/test/java/net/siteed/audiostream/AudioProcessorTest.kt +0 -56
  35. package/app.plugin.js +0 -1
  36. package/build/AudioAnalysis/AudioAnalysis.types.d.ts +0 -144
  37. package/build/AudioAnalysis/AudioAnalysis.types.d.ts.map +0 -1
  38. package/build/AudioAnalysis/AudioAnalysis.types.js +0 -3
  39. package/build/AudioAnalysis/AudioAnalysis.types.js.map +0 -1
  40. package/build/AudioAnalysis/extractAudioAnalysis.d.ts +0 -78
  41. package/build/AudioAnalysis/extractAudioAnalysis.d.ts.map +0 -1
  42. package/build/AudioAnalysis/extractAudioAnalysis.js +0 -229
  43. package/build/AudioAnalysis/extractAudioAnalysis.js.map +0 -1
  44. package/build/AudioAnalysis/extractWaveform.d.ts +0 -8
  45. package/build/AudioAnalysis/extractWaveform.d.ts.map +0 -1
  46. package/build/AudioAnalysis/extractWaveform.js +0 -11
  47. package/build/AudioAnalysis/extractWaveform.js.map +0 -1
  48. package/build/AudioRecorder.provider.d.ts +0 -11
  49. package/build/AudioRecorder.provider.d.ts.map +0 -1
  50. package/build/AudioRecorder.provider.js +0 -37
  51. package/build/AudioRecorder.provider.js.map +0 -1
  52. package/build/ExpoAudioStream.native.d.ts +0 -3
  53. package/build/ExpoAudioStream.native.d.ts.map +0 -1
  54. package/build/ExpoAudioStream.native.js +0 -6
  55. package/build/ExpoAudioStream.native.js.map +0 -1
  56. package/build/ExpoAudioStream.types.d.ts +0 -206
  57. package/build/ExpoAudioStream.types.d.ts.map +0 -1
  58. package/build/ExpoAudioStream.types.js +0 -2
  59. package/build/ExpoAudioStream.types.js.map +0 -1
  60. package/build/ExpoAudioStream.web.d.ts +0 -59
  61. package/build/ExpoAudioStream.web.d.ts.map +0 -1
  62. package/build/ExpoAudioStream.web.js +0 -285
  63. package/build/ExpoAudioStream.web.js.map +0 -1
  64. package/build/ExpoAudioStreamModule.d.ts +0 -3
  65. package/build/ExpoAudioStreamModule.d.ts.map +0 -1
  66. package/build/ExpoAudioStreamModule.js +0 -239
  67. package/build/ExpoAudioStreamModule.js.map +0 -1
  68. package/build/WebRecorder.web.d.ts +0 -119
  69. package/build/WebRecorder.web.d.ts.map +0 -1
  70. package/build/WebRecorder.web.js +0 -436
  71. package/build/WebRecorder.web.js.map +0 -1
  72. package/build/constants.d.ts +0 -11
  73. package/build/constants.d.ts.map +0 -1
  74. package/build/constants.js +0 -14
  75. package/build/constants.js.map +0 -1
  76. package/build/events.d.ts +0 -26
  77. package/build/events.d.ts.map +0 -1
  78. package/build/events.js +0 -21
  79. package/build/events.js.map +0 -1
  80. package/build/index.d.ts.map +0 -1
  81. package/build/index.js.map +0 -1
  82. package/build/useAudioRecorder.d.ts +0 -21
  83. package/build/useAudioRecorder.d.ts.map +0 -1
  84. package/build/useAudioRecorder.js +0 -427
  85. package/build/useAudioRecorder.js.map +0 -1
  86. package/build/utils/BlobFix.d.ts +0 -9
  87. package/build/utils/BlobFix.d.ts.map +0 -1
  88. package/build/utils/BlobFix.js +0 -498
  89. package/build/utils/BlobFix.js.map +0 -1
  90. package/build/utils/audioProcessing.d.ts +0 -24
  91. package/build/utils/audioProcessing.d.ts.map +0 -1
  92. package/build/utils/audioProcessing.js +0 -133
  93. package/build/utils/audioProcessing.js.map +0 -1
  94. package/build/utils/concatenateBuffers.d.ts +0 -8
  95. package/build/utils/concatenateBuffers.d.ts.map +0 -1
  96. package/build/utils/concatenateBuffers.js +0 -21
  97. package/build/utils/concatenateBuffers.js.map +0 -1
  98. package/build/utils/convertPCMToFloat32.d.ts +0 -13
  99. package/build/utils/convertPCMToFloat32.d.ts.map +0 -1
  100. package/build/utils/convertPCMToFloat32.js +0 -120
  101. package/build/utils/convertPCMToFloat32.js.map +0 -1
  102. package/build/utils/encodingToBitDepth.d.ts +0 -5
  103. package/build/utils/encodingToBitDepth.d.ts.map +0 -1
  104. package/build/utils/encodingToBitDepth.js +0 -13
  105. package/build/utils/encodingToBitDepth.js.map +0 -1
  106. package/build/utils/getWavFileInfo.d.ts +0 -26
  107. package/build/utils/getWavFileInfo.d.ts.map +0 -1
  108. package/build/utils/getWavFileInfo.js +0 -92
  109. package/build/utils/getWavFileInfo.js.map +0 -1
  110. package/build/utils/writeWavHeader.d.ts +0 -49
  111. package/build/utils/writeWavHeader.d.ts.map +0 -1
  112. package/build/utils/writeWavHeader.js +0 -91
  113. package/build/utils/writeWavHeader.js.map +0 -1
  114. package/build/workers/InlineFeaturesExtractor.web.d.ts +0 -2
  115. package/build/workers/InlineFeaturesExtractor.web.d.ts.map +0 -1
  116. package/build/workers/InlineFeaturesExtractor.web.js +0 -828
  117. package/build/workers/InlineFeaturesExtractor.web.js.map +0 -1
  118. package/build/workers/inlineAudioWebWorker.web.d.ts +0 -2
  119. package/build/workers/inlineAudioWebWorker.web.d.ts.map +0 -1
  120. package/build/workers/inlineAudioWebWorker.web.js +0 -157
  121. package/build/workers/inlineAudioWebWorker.web.js.map +0 -1
  122. package/expo-module.config.json +0 -9
  123. package/ios/AudioAnalysisData.swift +0 -74
  124. package/ios/AudioNotificationManager.swift +0 -135
  125. package/ios/AudioProcessingHelpers.swift +0 -743
  126. package/ios/AudioProcessor.swift +0 -858
  127. package/ios/AudioStreamError.swift +0 -7
  128. package/ios/AudioStreamManager.swift +0 -1708
  129. package/ios/AudioStreamManagerDelegate.swift +0 -16
  130. package/ios/DataPoint.swift +0 -54
  131. package/ios/DecodingConfig.swift +0 -47
  132. package/ios/ExpoAudioStream.podspec +0 -27
  133. package/ios/ExpoAudioStreamModule.swift +0 -698
  134. package/ios/FFT.swift +0 -62
  135. package/ios/Features.swift +0 -95
  136. package/ios/Logger.swift +0 -7
  137. package/ios/NotificationExtension.swift +0 -15
  138. package/ios/RecordingResult.swift +0 -22
  139. package/ios/RecordingSettings.swift +0 -265
  140. package/ios/WaveformExtractor.swift +0 -105
  141. package/plugin/build/index.d.ts +0 -21
  142. package/plugin/build/index.js +0 -191
  143. package/plugin/src/index.ts +0 -278
  144. package/plugin/tsconfig.json +0 -10
  145. package/plugin/tsconfig.tsbuildinfo +0 -1
  146. package/src/AudioAnalysis/AudioAnalysis.types.ts +0 -165
  147. package/src/AudioAnalysis/extractAudioAnalysis.ts +0 -370
  148. package/src/AudioAnalysis/extractWaveform.ts +0 -22
  149. package/src/AudioRecorder.provider.tsx +0 -54
  150. package/src/ExpoAudioStream.native.ts +0 -6
  151. package/src/ExpoAudioStream.types.ts +0 -329
  152. package/src/ExpoAudioStream.web.ts +0 -359
  153. package/src/ExpoAudioStreamModule.ts +0 -286
  154. package/src/WebRecorder.web.ts +0 -580
  155. package/src/constants.ts +0 -18
  156. package/src/events.ts +0 -60
  157. package/src/useAudioRecorder.tsx +0 -620
  158. package/src/utils/BlobFix.ts +0 -559
  159. package/src/utils/audioProcessing.ts +0 -205
  160. package/src/utils/concatenateBuffers.ts +0 -24
  161. package/src/utils/convertPCMToFloat32.ts +0 -170
  162. package/src/utils/encodingToBitDepth.ts +0 -18
  163. package/src/utils/getWavFileInfo.ts +0 -132
  164. package/src/utils/writeWavHeader.ts +0 -114
  165. package/src/workers/InlineFeaturesExtractor.web.tsx +0 -827
  166. package/src/workers/inlineAudioWebWorker.web.tsx +0 -156
@@ -1,105 +0,0 @@
1
- apply plugin: 'com.android.library'
2
- apply plugin: 'kotlin-android'
3
- apply plugin: 'maven-publish'
4
-
5
- group = 'net.siteed.audiostream'
6
- version = '0.1.0'
7
-
8
- buildscript {
9
- def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
10
- if (expoModulesCorePlugin.exists()) {
11
- apply from: expoModulesCorePlugin
12
- applyKotlinExpoModulesCorePlugin()
13
- }
14
-
15
- // Simple helper that allows the root project to override versions declared by this library.
16
- ext.safeExtGet = { prop, fallback ->
17
- rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
18
- }
19
-
20
- // Ensures backward compatibility
21
- ext.getKotlinVersion = {
22
- if (ext.has("kotlinVersion")) {
23
- ext.kotlinVersion()
24
- } else {
25
- ext.safeExtGet("kotlinVersion", "1.8.10")
26
- }
27
- }
28
-
29
- repositories {
30
- mavenCentral()
31
- }
32
-
33
- dependencies {
34
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
35
- }
36
- }
37
-
38
- afterEvaluate {
39
- publishing {
40
- publications {
41
- release(MavenPublication) {
42
- from components.release
43
- }
44
- }
45
- repositories {
46
- maven {
47
- url = mavenLocal().url
48
- }
49
- }
50
- }
51
- }
52
-
53
- android {
54
- compileSdkVersion safeExtGet("compileSdkVersion", 34)
55
-
56
- def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
57
- if (agpVersion.tokenize('.')[0].toInteger() < 8) {
58
- compileOptions {
59
- sourceCompatibility JavaVersion.VERSION_17
60
- targetCompatibility JavaVersion.VERSION_17
61
- }
62
-
63
- tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
64
- kotlinOptions {
65
- jvmTarget = '17'
66
- }
67
- }
68
- }
69
-
70
- namespace "net.siteed.audiostream"
71
- defaultConfig {
72
- minSdkVersion safeExtGet("minSdkVersion", 21)
73
- targetSdkVersion safeExtGet("targetSdkVersion", 34)
74
- versionCode 1
75
- versionName "0.1.0"
76
- }
77
- lintOptions {
78
- abortOnError false
79
- }
80
- publishing {
81
- singleVariant("release") {
82
- withSourcesJar()
83
- }
84
- }
85
- }
86
-
87
- repositories {
88
- mavenCentral()
89
- }
90
-
91
- dependencies {
92
- implementation project(':expo-modules-core')
93
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
94
-
95
- // Add testing dependencies
96
- testImplementation 'junit:junit:4.13.2'
97
- testImplementation 'org.jetbrains.kotlin:kotlin-test:1.8.10'
98
- testImplementation 'org.jetbrains.kotlin:kotlin-test-junit:1.8.10'
99
- }
100
-
101
- kotlin {
102
- jvmToolchain {
103
- languageVersion.set(JavaLanguageVersion.of(17))
104
- }
105
- }
@@ -1,27 +0,0 @@
1
- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
- <!-- Permissions will be merged into the app's manifest -->
3
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
4
- <uses-permission android:name="android.permission.RECORD_AUDIO"/>
5
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
6
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"/>
7
- <uses-permission android:name="android.permission.WAKE_LOCK" />
8
- <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
9
-
10
- <application>
11
- <receiver
12
- android:name=".RecordingActionReceiver"
13
- android:exported="false">
14
- <intent-filter>
15
- <action android:name="PAUSE_RECORDING" />
16
- <action android:name="RESUME_RECORDING" />
17
- <action android:name="STOP_RECORDING" />
18
- </intent-filter>
19
- </receiver>
20
-
21
- <service
22
- android:name=".AudioRecordingService"
23
- android:enabled="true"
24
- android:exported="false"
25
- android:foregroundServiceType="microphone" />
26
- </application>
27
- </manifest>
@@ -1,166 +0,0 @@
1
- // net/siteed/audiostream/AudioAnalysisData.kt
2
- package net.siteed.audiostream
3
-
4
- import android.os.Bundle
5
- import androidx.core.os.bundleOf
6
-
7
- data class SpeechFeatures(
8
- val isActive: Boolean,
9
- val speakerId: Int? = null
10
- ) {
11
- fun toDictionary(): Map<String, Any?> {
12
- return mapOf(
13
- "isActive" to isActive,
14
- "speakerId" to speakerId
15
- )
16
- }
17
-
18
- fun toBundle(): Bundle {
19
- return bundleOf(
20
- "isActive" to isActive,
21
- "speakerId" to speakerId
22
- )
23
- }
24
- }
25
-
26
- data class DataPoint(
27
- val id: Long,
28
- val amplitude: Float,
29
- val rms: Float,
30
- val dB: Float,
31
- val silent: Boolean,
32
- val features: Features? = null,
33
- val speech: SpeechFeatures? = null,
34
- val startTime: Float? = null,
35
- val endTime: Float? = null,
36
- val startPosition: Int? = null,
37
- val endPosition: Int? = null,
38
- val samples: Int = 0
39
- ) {
40
- fun toDictionary(): Map<String, Any?> {
41
- return mapOf(
42
- "id" to id,
43
- "amplitude" to amplitude,
44
- "rms" to rms,
45
- "dB" to dB,
46
- "silent" to silent,
47
- "features" to features?.toDictionary(),
48
- "speech" to speech?.toDictionary(),
49
- "startTime" to startTime,
50
- "endTime" to endTime,
51
- "startPosition" to startPosition,
52
- "endPosition" to endPosition,
53
- "samples" to samples
54
- )
55
- }
56
-
57
- fun toBundle(): Bundle {
58
- return bundleOf(
59
- "id" to id,
60
- "amplitude" to amplitude,
61
- "rms" to rms,
62
- "dB" to dB,
63
- "silent" to silent,
64
- "features" to features?.toBundle(),
65
- "speech" to speech?.toBundle(),
66
- "startTime" to startTime,
67
- "endTime" to endTime,
68
- "startPosition" to startPosition,
69
- "endPosition" to endPosition,
70
- "samples" to samples
71
- )
72
- }
73
- }
74
-
75
- data class AudioAnalysisData(
76
- val segmentDurationMs: Int,
77
- val durationMs: Int,
78
- val bitDepth: Int,
79
- val numberOfChannels: Int,
80
- val sampleRate: Int,
81
- val samples: Int,
82
- val dataPoints: List<DataPoint>,
83
- val amplitudeRange: AmplitudeRange,
84
- val rmsRange: AmplitudeRange,
85
- val speechAnalysis: SpeechAnalysis? = null,
86
- val extractionTimeMs: Float
87
- ) {
88
- data class AmplitudeRange(val min: Float, val max: Float) {
89
- fun toDictionary(): Map<String, Float> {
90
- return mapOf("min" to min, "max" to max)
91
- }
92
-
93
- fun toBundle(): Bundle {
94
- return bundleOf("min" to min, "max" to max)
95
- }
96
- }
97
-
98
- data class SpeechAnalysis(
99
- val speakerChanges: List<SpeakerChange>
100
- ) {
101
- fun toDictionary(): Map<String, Any> {
102
- return mapOf(
103
- "speakerChanges" to speakerChanges.map { it.toDictionary() }
104
- )
105
- }
106
-
107
- fun toBundle(): Bundle {
108
- return bundleOf(
109
- "speakerChanges" to speakerChanges.map { it.toBundle() }.toTypedArray()
110
- )
111
- }
112
- }
113
-
114
- data class SpeakerChange(
115
- val timestamp: Long,
116
- val speakerId: Int
117
- ) {
118
- fun toDictionary(): Map<String, Any> {
119
- return mapOf(
120
- "timestamp" to timestamp,
121
- "speakerId" to speakerId
122
- )
123
- }
124
-
125
- fun toBundle(): Bundle {
126
- return bundleOf(
127
- "timestamp" to timestamp,
128
- "speakerId" to speakerId
129
- )
130
- }
131
- }
132
-
133
- fun toDictionary(): Map<String, Any?> {
134
- return mapOf(
135
- "segmentDurationMs" to segmentDurationMs,
136
- "durationMs" to durationMs,
137
- "bitDepth" to bitDepth,
138
- "numberOfChannels" to numberOfChannels,
139
- "sampleRate" to sampleRate,
140
- "samples" to samples,
141
- "dataPoints" to dataPoints.map { it.toDictionary() },
142
- "amplitudeRange" to amplitudeRange.toDictionary(),
143
- "rmsRange" to rmsRange.toDictionary(),
144
- "speechAnalysis" to speechAnalysis?.toDictionary(),
145
- "extractionTimeMs" to extractionTimeMs
146
- )
147
- }
148
-
149
- fun toBundle(): Bundle {
150
- val dataPointsBundleArray = dataPoints.map { it.toBundle() }.toTypedArray()
151
-
152
- return bundleOf(
153
- "segmentDurationMs" to segmentDurationMs,
154
- "durationMs" to durationMs,
155
- "bitDepth" to bitDepth,
156
- "numberOfChannels" to numberOfChannels,
157
- "sampleRate" to sampleRate,
158
- "samples" to samples,
159
- "dataPoints" to dataPointsBundleArray,
160
- "amplitudeRange" to amplitudeRange.toBundle(),
161
- "rmsRange" to rmsRange.toBundle(),
162
- "speechAnalysis" to speechAnalysis?.toBundle(),
163
- "extractionTimeMs" to extractionTimeMs
164
- )
165
- }
166
- }
@@ -1,9 +0,0 @@
1
- package net.siteed.audiostream
2
-
3
- import android.util.Base64
4
-
5
- class AudioDataEncoder {
6
- public fun encodeToBase64(rawData: ByteArray): String {
7
- return Base64.encodeToString(rawData, Base64.NO_WRAP)
8
- }
9
- }
@@ -1,131 +0,0 @@
1
- package net.siteed.audiostream
2
-
3
- import android.util.Log
4
- import java.io.File
5
- import java.io.IOException
6
- import java.io.OutputStream
7
- import java.io.RandomAccessFile
8
- import java.util.UUID
9
-
10
- class AudioFileHandler(private val filesDir: File) {
11
- // Method to write WAV file header
12
- fun writeWavHeader(out: OutputStream, sampleRateInHz: Int, channels: Int, bitDepth: Int) {
13
- val header = ByteArray(44)
14
- val byteRate = sampleRateInHz * channels * bitDepth / 8
15
- val blockAlign = channels * bitDepth / 8
16
-
17
- // RIFF/WAVE header
18
- "RIFF".toByteArray().copyInto(header, 0)
19
- // (file size - 8) to be updated later
20
- header[4] = 0 // Placeholder
21
- header[5] = 0 // Placeholder
22
- header[6] = 0 // Placeholder
23
- header[7] = 0 // Placeholder
24
- "WAVE".toByteArray().copyInto(header, 8)
25
- "fmt ".toByteArray().copyInto(header, 12)
26
-
27
- // 16 for PCM
28
- header[16] = 16
29
- header[17] = 0
30
- header[18] = 0
31
- header[19] = 0
32
-
33
- // PCM format ID
34
- header[20] = 1 // Audio format 1 for PCM (not compressed)
35
- header[21] = 0
36
-
37
- // Number of channels
38
- header[22] = (channels and 0xff).toByte()
39
- header[23] = (channels shr 8 and 0xff).toByte()
40
-
41
- // Sample rate
42
- header[24] = (sampleRateInHz and 0xff).toByte()
43
- header[25] = (sampleRateInHz shr 8 and 0xff).toByte()
44
- header[26] = (sampleRateInHz shr 16 and 0xff).toByte()
45
- header[27] = (sampleRateInHz shr 24 and 0xff).toByte()
46
-
47
- // Byte rate
48
- header[28] = (byteRate and 0xff).toByte()
49
- header[29] = (byteRate shr 8 and 0xff).toByte()
50
- header[30] = (byteRate shr 16 and 0xff).toByte()
51
- header[31] = (byteRate shr 24 and 0xff).toByte()
52
-
53
- // Block align
54
- header[32] = (blockAlign and 0xff).toByte()
55
- header[33] = (blockAlign shr 8 and 0xff).toByte()
56
-
57
- // Bits per sample
58
- header[34] = (bitDepth and 0xff).toByte()
59
- header[35] = (bitDepth shr 8 and 0xff).toByte()
60
-
61
- // Data chunk
62
- "data".toByteArray().copyInto(header, 36)
63
- // Data size to be updated later
64
- header[40] = 0 // Placeholder
65
- header[41] = 0 // Placeholder
66
- header[42] = 0 // Placeholder
67
- header[43] = 0 // Placeholder
68
-
69
- out.write(header, 0, 44)
70
- }
71
-
72
- fun updateWavHeader(file: File) {
73
- try {
74
- RandomAccessFile(file, "rw").use { raf ->
75
- val fileSize = raf.length()
76
- val dataSize = fileSize - 44 // Subtract the header size
77
-
78
- raf.seek(4) // Write correct file size, excluding the first 8 bytes of the RIFF header
79
- raf.writeInt(Integer.reverseBytes((dataSize + 36).toInt()))
80
-
81
- raf.seek(40) // Go to the data size position
82
- raf.writeInt(Integer.reverseBytes(dataSize.toInt())) // Write the size of the data segment
83
- }
84
- } catch (e: IOException) {
85
- println("Could not update WAV header: ${e.message}")
86
- }
87
- }
88
-
89
- fun clearAudioStorage() {
90
- filesDir.listFiles()?.forEach {
91
- it.delete()
92
- }
93
- }
94
-
95
- fun createAudioFile(extension: String): File {
96
- val timestamp = System.currentTimeMillis()
97
- val uuid = UUID.randomUUID().toString()
98
- val filename = "recording_${timestamp}_${uuid}.${extension}"
99
-
100
- return try {
101
- File(filesDir, filename).apply {
102
- parentFile?.mkdirs() // Create directories if they don't exist
103
- createNewFile() // Create the file
104
- }
105
- } catch (e: Exception) {
106
- Log.e(Constants.TAG, "Failed to create audio file", e)
107
- throw e
108
- }
109
- }
110
-
111
- fun deleteFile(file: File?): Boolean {
112
- return try {
113
- if (file == null) {
114
- Log.w(Constants.TAG, "Attempted to delete null file")
115
- false
116
- } else if (!file.exists()) {
117
- Log.w(Constants.TAG, "File does not exist: ${file.absolutePath}")
118
- false
119
- } else {
120
- val wasDeleted = file.delete()
121
- if (!wasDeleted) {
122
- Log.w(Constants.TAG, "Failed to delete file: ${file.absolutePath}")
123
- }
124
- wasDeleted
125
- }
126
- } catch (e: Exception) {
127
- Log.e(Constants.TAG, "Error deleting file: ${file?.absolutePath}", e)
128
- false
129
- }
130
- }
131
- }
@@ -1,103 +0,0 @@
1
- package net.siteed.audiostream
2
-
3
- import android.media.AudioFormat
4
- import java.nio.ByteBuffer
5
- import java.nio.ByteOrder
6
-
7
- object AudioFormatUtils {
8
- /**
9
- * Converts a byte array of audio data to a float array based on the given encoding.
10
- * @param audioData The raw audio data in bytes.
11
- * @param encoding The encoding format (e.g., "pcm_8bit", "pcm_16bit", "pcm_32bit").
12
- * @return A float array with normalized audio samples in the range [-1.0, 1.0].
13
- */
14
- fun convertByteArrayToFloatArray(audioData: ByteArray, encoding: String): FloatArray {
15
- return when (encoding) {
16
- "pcm_8bit" -> {
17
- val floatArray = FloatArray(audioData.size)
18
- for (i in audioData.indices) {
19
- // Convert unsigned 8-bit to float in range [-1.0, 1.0]
20
- floatArray[i] = ((audioData[i].toInt() and 0xFF) - 128) / 128.0f
21
- }
22
- floatArray
23
- }
24
- "pcm_16bit" -> {
25
- val floatArray = FloatArray(audioData.size / 2)
26
- val buffer = ByteBuffer.wrap(audioData).order(ByteOrder.LITTLE_ENDIAN)
27
- for (i in floatArray.indices) {
28
- floatArray[i] = buffer.short / 32768.0f // Normalize to [-1.0, 1.0]
29
- }
30
- floatArray
31
- }
32
- "pcm_32bit" -> {
33
- val floatArray = FloatArray(audioData.size / 4)
34
- val buffer = ByteBuffer.wrap(audioData).order(ByteOrder.LITTLE_ENDIAN)
35
- for (i in floatArray.indices) {
36
- floatArray[i] = buffer.int / 2_147_483_648.0f // Normalize to [-1.0, 1.0]
37
- }
38
- floatArray
39
- }
40
- else -> {
41
- // Default to 16-bit PCM if encoding is not recognized
42
- val floatArray = FloatArray(audioData.size / 2)
43
- val buffer = ByteBuffer.wrap(audioData).order(ByteOrder.LITTLE_ENDIAN)
44
- for (i in floatArray.indices) {
45
- floatArray[i] = buffer.short / 32768.0f
46
- }
47
- floatArray
48
- }
49
- }
50
- }
51
-
52
- /**
53
- * Calculates the bit depth (number of bits per sample) based on the encoding string.
54
- * @param encoding The encoding format (e.g., "pcm_8bit", "pcm_16bit", "pcm_32bit").
55
- * @return The bit depth as an integer.
56
- */
57
- fun getBitDepth(encoding: String): Int {
58
- return when (encoding) {
59
- "pcm_8bit" -> 8
60
- "pcm_16bit" -> 16
61
- "pcm_32bit" -> 32
62
- else -> 16 // Default to 16-bit if not recognized
63
- }
64
- }
65
-
66
- /**
67
- * Determines the AudioFormat encoding constant based on the encoding string.
68
- * @param encoding The encoding format (e.g., "pcm_8bit", "pcm_16bit", "pcm_32bit").
69
- * @return The corresponding AudioFormat constant.
70
- */
71
- fun getAudioFormat(encoding: String): Int {
72
- return when (encoding) {
73
- "pcm_8bit" -> AudioFormat.ENCODING_PCM_8BIT
74
- "pcm_16bit" -> AudioFormat.ENCODING_PCM_16BIT
75
- "pcm_32bit" -> AudioFormat.ENCODING_PCM_FLOAT
76
- else -> AudioFormat.ENCODING_PCM_16BIT // Default to 16-bit PCM
77
- }
78
- }
79
-
80
- /**
81
- * Converts audio data between different bit depths
82
- * @param audioData The raw audio data
83
- * @param sourceBitDepth The original bit depth
84
- * @param targetBitDepth The desired bit depth
85
- * @return The converted audio data
86
- */
87
- fun convertBitDepth(audioData: ByteArray, sourceBitDepth: Int, targetBitDepth: Int): ByteArray {
88
- // First convert to float array for normalization
89
- val floatArray = convertByteArrayToFloatArray(audioData, "pcm_${sourceBitDepth}bit")
90
-
91
- // Convert back to bytes with new bit depth
92
- return when (targetBitDepth) {
93
- 8 -> floatArray.map { ((it + 1.0f) * 127.5f).toInt().toByte() }.toByteArray()
94
- 16 -> ByteBuffer.allocate(floatArray.size * 2).order(ByteOrder.LITTLE_ENDIAN).apply {
95
- floatArray.forEach { asShortBuffer().put((it * 32767f).toInt().toShort()) }
96
- }.array()
97
- 32 -> ByteBuffer.allocate(floatArray.size * 4).order(ByteOrder.LITTLE_ENDIAN).apply {
98
- floatArray.forEach { putFloat(it) }
99
- }.array()
100
- else -> throw IllegalArgumentException("Unsupported target bit depth: $targetBitDepth")
101
- }
102
- }
103
- }