From ff01a49bc303a9bdf58c6503724ef1e32b0b42f1 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sun, 15 Jan 2023 00:23:01 +0900 Subject: [PATCH] mp2 "hardware" delegation not working as hoped --- assets/disk0/tvdos/include/mp2dec.js | 15 +- .../net/torvald/tsvm/AudioJSR223Delegate.kt | 191 +++++++++++++++++- 2 files changed, 192 insertions(+), 14 deletions(-) diff --git a/assets/disk0/tvdos/include/mp2dec.js b/assets/disk0/tvdos/include/mp2dec.js index 9141f43..6677624 100644 --- a/assets/disk0/tvdos/include/mp2dec.js +++ b/assets/disk0/tvdos/include/mp2dec.js @@ -779,7 +779,7 @@ var kjmp2_decode_frame=function(mp2,fr,pcm,outL,outR) { }; }; } - let ppcm=0; +// let ppcm=0; // coefficient input and reconstruction for (part = 0; part < 3; ++part){ for (gr = 0; gr < 4; ++gr) { @@ -788,14 +788,10 @@ var kjmp2_decode_frame=function(mp2,fr,pcm,outL,outR) { for (sb = 0; sb < bound; ++sb){ for (ch = 0; ch < 2; ++ch){ read_samples(allocation[ch][sb], scalefactor[ch][sb][part], sample[ch][sb]); -// read_samples(allocation[ch][sb], scalefactor[ch][sb][part], &sample[ch][sb][0]); -// more pointer crap to fix }; }; for (sb = bound; sb < sblimit; ++sb) { read_samples(allocation[0][sb], scalefactor[0][sb][part], sample[0][sb]); -// read_samples(allocation[0][sb], scalefactor[0][sb][part], &sample[0][sb][0]); -// Above needs looking at do something about the pointer for (idx = 0; idx < 3; ++idx){ sample[1][sb][idx] = sample[0][sb][idx]; @@ -844,25 +840,26 @@ var kjmp2_decode_frame=function(mp2,fr,pcm,outL,outR) { sum = (sum + 8) >> 4; if (sum < -32768) {sum = -32768}; if (sum > 32767) {sum = 32767}; - //if(ch==0){l.push(sum/33000)}; - //if(ch==1){r.push(sum/33000)}; if (ch == 0) { pushL(sum) } if (ch == 1) { pushR(sum) } -// pcm[((idx << 6) | (j << 1) | ch)+ppcm] =sum; } } // end of synthesis channel loop } // end of synthesis sub-block loop + + // adjust PCM output pointer: decoded 3 * 32 = 96 stereo samples - ppcm += 192; +// ppcm += 192; } // decoding of the granule finished } + //;[pushSizeL, pushSizeR] = audio.mp2_synthesisLoop(read_samples, allocation, scalefactor, sblimit, mp2, sample, bound, outL, outR) if (pushSizeL != pushSizeR && pushSizeR > 0) { throw Error(`Push size mismatch -- U${pushSizeL} != R${pushSizeR}`) } serial.println(pushSizeL) return [frame_size, pushSizeL]; +// return [frame_size, 2304]; }; var kjmp2_make_mp2_state=function(){ diff --git a/tsvm_core/src/net/torvald/tsvm/AudioJSR223Delegate.kt b/tsvm_core/src/net/torvald/tsvm/AudioJSR223Delegate.kt index 967badb..e0a0172 100644 --- a/tsvm_core/src/net/torvald/tsvm/AudioJSR223Delegate.kt +++ b/tsvm_core/src/net/torvald/tsvm/AudioJSR223Delegate.kt @@ -1,11 +1,8 @@ package net.torvald.tsvm -import com.oracle.truffle.regex.util.TruffleReadOnlyMap -import javazoom.jl.decoder.LayerIIIDecoder.pretab import net.torvald.tsvm.peripheral.AudioAdapter import org.graalvm.polyglot.Value import kotlin.math.cos -import kotlin.math.sign /** * Created by minjaesong on 2022-12-31. @@ -83,7 +80,8 @@ class AudioJSR223Delegate(private val vm: VM) { private val synthNWin = Array(64) { i -> FloatArray(32) { j -> cos(((16 + i) * (2 * j + 1)) * (Math.PI / 64.0)).toFloat() } } - private val synthDtbl = floatArrayOf(0.000000000f, -0.000015259f, -0.000015259f, -0.000015259f, + private val synthDtbl = floatArrayOf( + 0.000000000f, -0.000015259f, -0.000015259f, -0.000015259f, -0.000015259f, -0.000015259f, -0.000015259f, -0.000030518f, -0.000030518f, -0.000030518f, -0.000030518f, -0.000045776f, -0.000045776f, -0.000061035f, -0.000061035f, -0.000076294f, @@ -210,7 +208,8 @@ class AudioJSR223Delegate(private val vm: VM) { 0.000076294f, 0.000076294f, 0.000061035f, 0.000061035f, 0.000045776f, 0.000045776f, 0.000030518f, 0.000030518f, 0.000030518f, 0.000030518f, 0.000015259f, 0.000015259f, - 0.000015259f, 0.000015259f, 0.000015259f, 0.000015259f,) + 0.000015259f, 0.000015259f, 0.000015259f, 0.000015259f, + ) private val imdctWinData = Array(4) { DoubleArray(36) } private val cosN12 = Array(6) { DoubleArray(12) } @@ -401,4 +400,186 @@ class AudioJSR223Delegate(private val vm: VM) { } } } + + + + + + + + + + + + private val N = Array(64) { i -> IntArray(32) { j -> + Math.floor(256.0 * Math.cos((16 + i) * ((j shl 1) + 1) * 0.0490873852123405)).toInt() + } } + private val U = IntArray(512) + private val D= arrayOf( + 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000,-0x00001, + -0x00001,-0x00001,-0x00001,-0x00002,-0x00002,-0x00003,-0x00003,-0x00004, + -0x00004,-0x00005,-0x00006,-0x00006,-0x00007,-0x00008,-0x00009,-0x0000A, + -0x0000C,-0x0000D,-0x0000F,-0x00010,-0x00012,-0x00014,-0x00017,-0x00019, + -0x0001C,-0x0001E,-0x00022,-0x00025,-0x00028,-0x0002C,-0x00030,-0x00034, + -0x00039,-0x0003E,-0x00043,-0x00048,-0x0004E,-0x00054,-0x0005A,-0x00060, + -0x00067,-0x0006E,-0x00074,-0x0007C,-0x00083,-0x0008A,-0x00092,-0x00099, + -0x000A0,-0x000A8,-0x000AF,-0x000B6,-0x000BD,-0x000C3,-0x000C9,-0x000CF, + 0x000D5, 0x000DA, 0x000DE, 0x000E1, 0x000E3, 0x000E4, 0x000E4, 0x000E3, + 0x000E0, 0x000DD, 0x000D7, 0x000D0, 0x000C8, 0x000BD, 0x000B1, 0x000A3, + 0x00092, 0x0007F, 0x0006A, 0x00053, 0x00039, 0x0001D,-0x00001,-0x00023, + -0x00047,-0x0006E,-0x00098,-0x000C4,-0x000F3,-0x00125,-0x0015A,-0x00190, + -0x001CA,-0x00206,-0x00244,-0x00284,-0x002C6,-0x0030A,-0x0034F,-0x00396, + -0x003DE,-0x00427,-0x00470,-0x004B9,-0x00502,-0x0054B,-0x00593,-0x005D9, + -0x0061E,-0x00661,-0x006A1,-0x006DE,-0x00718,-0x0074D,-0x0077E,-0x007A9, + -0x007D0,-0x007EF,-0x00808,-0x0081A,-0x00824,-0x00826,-0x0081F,-0x0080E, + 0x007F5, 0x007D0, 0x007A0, 0x00765, 0x0071E, 0x006CB, 0x0066C, 0x005FF, + 0x00586, 0x00500, 0x0046B, 0x003CA, 0x0031A, 0x0025D, 0x00192, 0x000B9, + -0x0002C,-0x0011F,-0x00220,-0x0032D,-0x00446,-0x0056B,-0x0069B,-0x007D5, + -0x00919,-0x00A66,-0x00BBB,-0x00D16,-0x00E78,-0x00FDE,-0x01148,-0x012B3, + -0x01420,-0x0158C,-0x016F6,-0x0185C,-0x019BC,-0x01B16,-0x01C66,-0x01DAC, + -0x01EE5,-0x02010,-0x0212A,-0x02232,-0x02325,-0x02402,-0x024C7,-0x02570, + -0x025FE,-0x0266D,-0x026BB,-0x026E6,-0x026ED,-0x026CE,-0x02686,-0x02615, + -0x02577,-0x024AC,-0x023B2,-0x02287,-0x0212B,-0x01F9B,-0x01DD7,-0x01BDD, + 0x019AE, 0x01747, 0x014A8, 0x011D1, 0x00EC0, 0x00B77, 0x007F5, 0x0043A, + 0x00046,-0x003E5,-0x00849,-0x00CE3,-0x011B4,-0x016B9,-0x01BF1,-0x0215B, + -0x026F6,-0x02CBE,-0x032B3,-0x038D3,-0x03F1A,-0x04586,-0x04C15,-0x052C4, + -0x05990,-0x06075,-0x06771,-0x06E80,-0x0759F,-0x07CCA,-0x083FE,-0x08B37, + -0x09270,-0x099A7,-0x0A0D7,-0x0A7FD,-0x0AF14,-0x0B618,-0x0BD05,-0x0C3D8, + -0x0CA8C,-0x0D11D,-0x0D789,-0x0DDC9,-0x0E3DC,-0x0E9BD,-0x0EF68,-0x0F4DB, + -0x0FA12,-0x0FF09,-0x103BD,-0x1082C,-0x10C53,-0x1102E,-0x113BD,-0x116FB, + -0x119E8,-0x11C82,-0x11EC6,-0x120B3,-0x12248,-0x12385,-0x12467,-0x124EF, + 0x1251E, 0x124F0, 0x12468, 0x12386, 0x12249, 0x120B4, 0x11EC7, 0x11C83, + 0x119E9, 0x116FC, 0x113BE, 0x1102F, 0x10C54, 0x1082D, 0x103BE, 0x0FF0A, + 0x0FA13, 0x0F4DC, 0x0EF69, 0x0E9BE, 0x0E3DD, 0x0DDCA, 0x0D78A, 0x0D11E, + 0x0CA8D, 0x0C3D9, 0x0BD06, 0x0B619, 0x0AF15, 0x0A7FE, 0x0A0D8, 0x099A8, + 0x09271, 0x08B38, 0x083FF, 0x07CCB, 0x075A0, 0x06E81, 0x06772, 0x06076, + 0x05991, 0x052C5, 0x04C16, 0x04587, 0x03F1B, 0x038D4, 0x032B4, 0x02CBF, + 0x026F7, 0x0215C, 0x01BF2, 0x016BA, 0x011B5, 0x00CE4, 0x0084A, 0x003E6, + -0x00045,-0x00439,-0x007F4,-0x00B76,-0x00EBF,-0x011D0,-0x014A7,-0x01746, + 0x019AE, 0x01BDE, 0x01DD8, 0x01F9C, 0x0212C, 0x02288, 0x023B3, 0x024AD, + 0x02578, 0x02616, 0x02687, 0x026CF, 0x026EE, 0x026E7, 0x026BC, 0x0266E, + 0x025FF, 0x02571, 0x024C8, 0x02403, 0x02326, 0x02233, 0x0212B, 0x02011, + 0x01EE6, 0x01DAD, 0x01C67, 0x01B17, 0x019BD, 0x0185D, 0x016F7, 0x0158D, + 0x01421, 0x012B4, 0x01149, 0x00FDF, 0x00E79, 0x00D17, 0x00BBC, 0x00A67, + 0x0091A, 0x007D6, 0x0069C, 0x0056C, 0x00447, 0x0032E, 0x00221, 0x00120, + 0x0002D,-0x000B8,-0x00191,-0x0025C,-0x00319,-0x003C9,-0x0046A,-0x004FF, + -0x00585,-0x005FE,-0x0066B,-0x006CA,-0x0071D,-0x00764,-0x0079F,-0x007CF, + 0x007F5, 0x0080F, 0x00820, 0x00827, 0x00825, 0x0081B, 0x00809, 0x007F0, + 0x007D1, 0x007AA, 0x0077F, 0x0074E, 0x00719, 0x006DF, 0x006A2, 0x00662, + 0x0061F, 0x005DA, 0x00594, 0x0054C, 0x00503, 0x004BA, 0x00471, 0x00428, + 0x003DF, 0x00397, 0x00350, 0x0030B, 0x002C7, 0x00285, 0x00245, 0x00207, + 0x001CB, 0x00191, 0x0015B, 0x00126, 0x000F4, 0x000C5, 0x00099, 0x0006F, + 0x00048, 0x00024, 0x00002,-0x0001C,-0x00038,-0x00052,-0x00069,-0x0007E, + -0x00091,-0x000A2,-0x000B0,-0x000BC,-0x000C7,-0x000CF,-0x000D6,-0x000DC, + -0x000DF,-0x000E2,-0x000E3,-0x000E3,-0x000E2,-0x000E0,-0x000DD,-0x000D9, + 0x000D5, 0x000D0, 0x000CA, 0x000C4, 0x000BE, 0x000B7, 0x000B0, 0x000A9, + 0x000A1, 0x0009A, 0x00093, 0x0008B, 0x00084, 0x0007D, 0x00075, 0x0006F, + 0x00068, 0x00061, 0x0005B, 0x00055, 0x0004F, 0x00049, 0x00044, 0x0003F, + 0x0003A, 0x00035, 0x00031, 0x0002D, 0x00029, 0x00026, 0x00023, 0x0001F, + 0x0001D, 0x0001A, 0x00018, 0x00015, 0x00013, 0x00011, 0x00010, 0x0000E, + 0x0000D, 0x0000B, 0x0000A, 0x00009, 0x00008, 0x00007, 0x00007, 0x00006, + 0x00005, 0x00005, 0x00004, 0x00004, 0x00003, 0x00003, 0x00002, 0x00002, + 0x00002, 0x00002, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001); + + fun mp2_synthesisLoop(read_samples: Value, allocation: Value, scalefactor: Value, sblimit: Long, mp2: Value, sample: Value, bound: Long, outL: Long, outR: Long): IntArray { + val V = mp2.getMember("V") + + var pushSizeL = 0 + var pushSizeR = 0 + fun pushL(sampleL: Int) { + vm.poke(outL + pushSizeL + 0, (sampleL).toByte()) + vm.poke(outL + pushSizeL + 1, (sampleL ushr 8).toByte()) + pushSizeL += 2 + } + fun pushR(sampleR: Int) { + vm.poke(outR + pushSizeR + 0, (sampleR).toByte()) + vm.poke(outR + pushSizeR + 1, (sampleR ushr 8).toByte()) + pushSizeR += 2 + } + + var ppcm = 0 + for (part in 0 until 3L){ + for (gr in 0 until 4L) { + + // read the samples + for (sb in 0 until bound) { + for (ch in 0 until 2L) { + read_samples.executeVoid(allocation.getArrayElement(ch).getArrayElement(sb), scalefactor.getArrayElement(ch).getArrayElement(sb).getArrayElement(part), sample.getArrayElement(ch).getArrayElement(sb)) + } + } + for (sb in bound until sblimit) { + read_samples.executeVoid(allocation.getArrayElement(0L).getArrayElement(sb), scalefactor.getArrayElement(0L).getArrayElement(sb).getArrayElement(part), sample.getArrayElement(0L).getArrayElement(sb)) + + for (idx in 0 until 3L){ + sample.getArrayElement(1L).getArrayElement(sb).setArrayElement(idx, sample.getArrayElement(0L).getArrayElement(sb).getArrayElement(idx)) + //sample[1][sb][idx] = sample[0][sb][idx] + } + } + for (ch in 0 until 2L){ + for (sb in sblimit until 32L){ + for (idx in 0 until 3L){ + sample.getArrayElement(ch).getArrayElement(sb).setArrayElement(idx, 0) +// sample[ch][sb][idx] = 0 + } + } + } + + // synthesis loop + for (idx in 0 until 3L) { + // shifting step + val table_idx = ((mp2.getMember("Voffs").asInt() - 64) and 1023).toLong() + mp2.putMember("Voffs", table_idx) + + for (ch in 0 until 2L) { + // matrixing + for (i in 0 until 64L) { + var sum = 0 + for (j in 0 until 32L) { + sum += N[i.toInt()][j.toInt()] * sample.getArrayElement(ch).getArrayElement(j).getArrayElement(idx).asInt() // 8b*15b=23b + } + // intermediate value is 28 bit (23 + 5), clamp to 14b + V.getArrayElement(ch).setArrayElement(table_idx + i, (sum + 8192) shr 14) +// mp2.V[ch][table_idx + i] = (sum + 8192) shr 14; + } + + // construction of U + for (i in 0 until 8L){ + for (j in 0 until 32L) { + U[((i shl 6) + j ).toInt()] = V.getArrayElement(ch).getArrayElement((table_idx + (i shl 7) + j ) and 1023).asInt() + U[((i shl 6) + j + 32L).toInt()] = V.getArrayElement(ch).getArrayElement((table_idx + (i shl 7) + j + 96) and 1023).asInt() + +// U[(i shl 6) + j] = mp2.V[ch][(table_idx + (i shl 7) + j ) and 1023] +// U[(i shl 6) + j + 32] = mp2.V[ch][(table_idx + (i shl 7) + j + 96) and 1023] + } + } + // apply window + for (i in 0 until 512){ + U[i] = (U[i] * D[i] + 32) shr 6 +// U[i] = (U[i] * D[i] + 32) shr 6 + } + // output samples + for (j in 0 until 32) { + var sum = 0 + for (i in 0 until 16){ + sum -= U[(i shl 5) + j] +// sum -= U[(i shl 5) + j] + } + sum = (sum + 8) shr 4 + if (sum < -32768) {sum = -32768} + if (sum > 32767) {sum = 32767} + if (ch == 0L) { pushL(sum) } + if (ch == 1L) { pushR(sum) } + } + } // end of synthesis channel loop + } // end of synthesis sub-block loop + + // adjust PCM output pointer: decoded 3 * 32 = 96 stereo samples + ppcm += 192; + } // decoding of the granule finished + + } + return intArrayOf(pushSizeL, pushSizeR) + } + + } \ No newline at end of file