I'm currently creating a waveform generator which reads .wav audio files. I would ideally like to have my program look as follows:
public data class Wave(path : Path) {
val audioSamples: ByteArray
val header : WaveHeader
val frames : Frames
{
if (!hasWavExtension(path))
throw WaveException(“Does not have the .wav file extension”)
val rawData = readRawData(path)
audioSamples = rawData.drop(WaveHeader.HeaderByteLength)
header = parseWaveHeader(rawData.take(WaveHeader.HeaderByteLength))
frames = readFrames(audioSamples, header)
}
Putting aside the limitation of the current implementation (a wave header isn’t strictly an X amount of bytes), the compiler complains because the .drop and take functions convert my ByteArray to Array<Byte>. Converting it back is possible, but a pain.
Attempts to elegantly convert the Array<Byte> back:
audioSamples = rawData.drop(WaveHeader.HeaderByteLength) as ByteArray // Exception, cannot convert
audioSamples = rawData.drop(WaveHeader.HeaderByteLength).copyToArray() as ByteArray // As above
audioSamples = byteArray(*rawData.drop(WaveHeader.HeaderByteLength).copyToArray()) // Syntax error, but this works for Array<String> ???
val samples = rawData.drop(WaveHeader.HeaderByteLength).copyToArray()
audioSamples = byteArray(*samples) // As above
Instead, I have to forego immutability and loop for the desired amount of bytes:
val samples = rawData.drop(WaveHeader.HeaderByteLength).copyToArray()
audioSamples = ByteArray(WaveHeader.HeaderByteLength)
for (sample in samples.withIndices())
audioSamples[sample.first] = sample.second
I would like to ask if there is any other way that I'm missing because of my inexperience? Could I create the behavior I want with an extension function? If so, how? Retrospectively, am I not even supposed to use TArrays when writing Kotlin? Is Kotlin designed with Array<T> in mind?