@@ -6,9 +6,26 @@ import org.junit.runner.RunWith
66import org.junit.Assert.assertArrayEquals
77import org.junit.Assert.assertEquals
88import org.junit.Assert.assertTrue
9+ import kotlin.test.DefaultAsserter.assertNotNull
910
1011@RunWith(AndroidJUnit4 ::class )
11- class WSPREncoderTest {
12+ class WSPREncoderTest
13+ {
14+ companion object
15+ {
16+ const val TEST_CALLSIGN = " AA0AAA"
17+ const val TEST_GRID = " FN20"
18+ const val TEST_POWER = 30
19+ const val TEST_FREQ_MHZ = 14.0956
20+
21+ // From jni_link.h: WSPR_SYMBOL_LENGTH = 8192
22+ // 162 symbols × 8192 samples/symbol × 2 bytes/sample (16-bit PCM)
23+ const val EXPECTED_PCM_BYTES = 162 * 8192 * 2 // = 2,654,208
24+
25+ // Native decoder requires 114s of audio:
26+ // 114s × 12,000 samples/s × 2 bytes/sample
27+ const val DECODER_REQUIRED_BYTES = 114 * 12_000 * 2 // = 2,736,000
28+ }
1229
1330 @Test
1431 fun testBasicEncodingMatchesJNI () {
@@ -285,4 +302,40 @@ class WSPREncoderTest {
285302
286303 println (" ✓ Ran $testCount comprehensive comparison tests - all passed!" )
287304 }
305+
306+ @Test
307+ fun wsprEncodeToPCM_returnsCorrectByteCount ()
308+ {
309+ val pcm = CJarInterface .WSPREncodeToPCM (
310+ TEST_CALLSIGN , TEST_GRID , TEST_POWER , 0 , false
311+ )
312+
313+ assertNotNull(" WSPREncodeToPCM returned null" , pcm)
314+ assertEquals(
315+ " PCM output size should be 162 symbols × 8192 samples × 2 bytes" ,
316+ EXPECTED_PCM_BYTES ,
317+ pcm.size
318+ )
319+ }
320+
321+ @Test
322+ fun wsprRoundTrip_decodesCallsignAndGrid ()
323+ {
324+ val encodedPcm = CJarInterface .WSPREncodeToPCM (
325+ TEST_CALLSIGN , TEST_GRID , TEST_POWER , 0 , false
326+ )
327+
328+ assertNotNull(" WSPREncodeToPCM returned null" , encodedPcm)
329+
330+ // Zero-pad to decoder minimum — encoded signal is 110.6s, decoder needs 114s
331+ val paddedBuffer = ByteArray (DECODER_REQUIRED_BYTES )
332+ encodedPcm.copyInto(paddedBuffer)
333+
334+ val results = CJarInterface .WSPRDecodeFromPcm (paddedBuffer, TEST_FREQ_MHZ , false )
335+
336+ assertNotNull(" WSPRDecodeFromPcm returned null" , results)
337+ assertTrue(" Decoder should recover at least one message" , results.isNotEmpty())
338+ assertEquals(" Decoded callsign should match" , TEST_CALLSIGN , results[0 ].call?.trim())
339+ assertEquals(" Decoded grid should match" , TEST_GRID , results[0 ].loc?.trim())
340+ }
288341}
0 commit comments