@@ -15,14 +15,14 @@ import (
1515 "runtime"
1616 "strconv"
1717 "strings"
18+ "sync"
1819 "testing"
1920)
2021
2122type conformanceKey struct {
22- vectorSet string
23- rate int
24- channels int
25- vector string
23+ rate int
24+ channels int
25+ vector string
2626}
2727
2828type conformanceResult struct {
@@ -48,58 +48,56 @@ func TestRFC6716Conformance(t *testing.T) {
4848 "01" , "02" , "03" , "04" , "05" , "06" ,
4949 "07" , "08" , "09" , "10" , "11" , "12" ,
5050 }
51- vectorSets := []string {"rfc6716" , "rfc8251" }
5251
5352 refDir , vectorRoot := conformanceDataPaths (t )
5453
5554 opusCompare := buildRFC6716ReferenceTools (t , refDir )
5655 results := make (map [conformanceKey ]conformanceResult )
56+ var resultsMu sync.Mutex
57+
58+ t .Run ("vectors" , func (t * testing.T ) {
59+ for _ , rate := range rates {
60+ for _ , channels := range channelCounts {
61+ for _ , vector := range vectors {
62+ key := conformanceKey {
63+ rate : rate ,
64+ channels : channels ,
65+ vector : vector ,
66+ }
67+ t .Run (
68+ fmt .Sprintf ("rate_%d/channels_%d/testvector%s" , rate , channels , vector ),
69+ func (t * testing.T ) {
70+ t .Parallel ()
5771
58- for _ , vectorSet := range vectorSets {
59- vectorDir := filepath .Join (vectorRoot , vectorSet )
60- t .Run (vectorSet , func (t * testing.T ) {
61- for _ , rate := range rates {
62- for _ , channels := range channelCounts {
63- t .Run (fmt .Sprintf ("rate_%d/channels_%d" , rate , channels ), func (t * testing.T ) {
64- for _ , vector := range vectors {
65- key := conformanceKey {
66- vectorSet : vectorSet ,
67- rate : rate ,
68- channels : channels ,
69- vector : vector ,
70- }
71- ran := false
7272 quality := ""
73- passed := t .Run ("testvector" + vector , func (t * testing.T ) {
74- ran = true
75- bitstream := filepath .Join (vectorDir , "testvector" + vector + ".bit" )
76- referencePCM := filepath .Join (vectorDir , "testvector" + vector + ".dec" )
77- alternateReferencePCM := filepath .Join (vectorDir , "testvector" + vector + "m.dec" )
78- goPCM := filepath .Join (t .TempDir (), "go.pcm" )
79-
80- decodeRFC6716Vector (t , rate , channels , bitstream , goPCM )
81- quality = compareRFC6716Output (
82- t ,
83- opusCompare ,
84- rate ,
85- channels ,
86- referencePCM ,
87- alternateReferencePCM ,
88- goPCM ,
89- )
90- })
91- if ran {
92- results [key ] = conformanceResult {passed : passed , quality : quality }
93- }
94- }
95- })
73+ defer func () {
74+ resultsMu .Lock ()
75+ results [key ] = conformanceResult {passed : ! t .Failed (), quality : quality }
76+ resultsMu .Unlock ()
77+ }()
78+
79+ bitstream := conformanceBitstreamPath (t , vectorRoot , vector )
80+ referencePCMs := conformanceReferencePCMs (vectorRoot , vector )
81+ goPCM := filepath .Join (t .TempDir (), "go.pcm" )
82+
83+ decodeRFC6716Vector (t , rate , channels , bitstream , goPCM )
84+ quality = compareRFC6716Output (
85+ t ,
86+ opusCompare ,
87+ rate ,
88+ channels ,
89+ referencePCMs ,
90+ goPCM ,
91+ )
92+ },
93+ )
9694 }
9795 }
98- })
99- }
96+ }
97+ })
10098
101- printConformanceMatrix (results , vectorSets , rates , channelCounts , vectors )
102- writeConformanceMarkdown (t , os .Getenv (envConformanceMarkdown ), results , vectorSets , rates , channelCounts , vectors )
99+ printConformanceMatrix (results , rates , channelCounts , vectors )
100+ writeConformanceMarkdown (t , os .Getenv (envConformanceMarkdown ), results , rates , channelCounts , vectors )
103101}
104102
105103func conformanceDataPaths (t * testing.T ) (refDir , vectorRoot string ) {
@@ -118,42 +116,62 @@ func compareRFC6716Output(
118116 t * testing.T ,
119117 opusCompare string ,
120118 rate , channels int ,
121- referencePCM , alternateReferencePCM , goPCM string ,
119+ referencePCMs []string ,
120+ goPCM string ,
122121) string {
123122 t .Helper ()
124123
125- out , err := runOpusCompare (opusCompare , rate , channels , referencePCM , goPCM )
126- if err == nil {
127- quality := opusCompareQuality (out )
128- printOpusCompareQuality (t , quality )
124+ checkedReference := false
125+ var failures []string
126+ for _ , referencePCM := range referencePCMs {
127+ if _ , err := os .Stat (referencePCM ); err != nil {
128+ continue
129+ }
130+ checkedReference = true
131+ out , err := runOpusCompare (opusCompare , rate , channels , referencePCM , goPCM )
132+ if err == nil {
133+ quality := opusCompareQuality (out )
134+ printOpusCompareQuality (t , quality )
129135
130- return quality
136+ return quality
137+ }
138+ failures = append (failures , fmt .Sprintf ("%s: %v\n %s" , referencePCM , err , out ))
139+ }
140+ if ! checkedReference {
141+ t .Fatalf ("no reference PCM found among %v" , referencePCMs )
131142 }
132- primaryErr := err
133- primaryOut := out
134143
135- if _ , err := os .Stat (alternateReferencePCM ); err != nil {
136- t .Fatalf ("opus_compare failed: %v\n %s" , primaryErr , primaryOut )
144+ t .Fatalf ("opus_compare failed for all references:\n %s" , strings .Join (failures , "\n " ))
137145
138- return ""
139- }
146+ return ""
147+ }
140148
141- out , err = runOpusCompare (opusCompare , rate , channels , alternateReferencePCM , goPCM )
142- if err != nil {
143- t .Fatalf (
144- "opus_compare failed for both references: primary=%v alternate=%v\n primary:\n %s\n alternate:\n %s" ,
145- primaryErr ,
146- err ,
147- primaryOut ,
148- out ,
149- )
149+ func conformanceBitstreamPath (t * testing.T , vectorRoot , vector string ) string {
150+ t .Helper ()
150151
151- return ""
152+ // RFC 8251 Section 11 keeps the decoder input bitstreams unchanged, so the
153+ // newer archive is the preferred source and the RFC 6716 archive is an
154+ // equivalent fallback when only the legacy bundle is available.
155+ for _ , vectorSet := range []string {"rfc8251" , "rfc6716" } {
156+ path := filepath .Join (vectorRoot , vectorSet , "testvector" + vector + ".bit" )
157+ if _ , err := os .Stat (path ); err == nil {
158+ return path
159+ }
152160 }
153- quality := opusCompareQuality (out )
154- printOpusCompareQuality (t , quality )
155161
156- return quality
162+ t .Fatalf ("missing testvector%s.bit in RFC 8251 or RFC 6716 vectors" , vector )
163+
164+ return ""
165+ }
166+
167+ func conformanceReferencePCMs (vectorRoot , vector string ) []string {
168+ // RFC 8251 Section 11 permits either the original RFC 6716 output set or
169+ // one of the updated output sets for the same unchanged input bitstreams.
170+ return []string {
171+ filepath .Join (vectorRoot , "rfc8251" , "testvector" + vector + ".dec" ),
172+ filepath .Join (vectorRoot , "rfc8251" , "testvector" + vector + "m.dec" ),
173+ filepath .Join (vectorRoot , "rfc6716" , "testvector" + vector + ".dec" ),
174+ }
157175}
158176
159177func buildRFC6716ReferenceTools (t * testing.T , refDir string ) (opusCompare string ) {
@@ -309,7 +327,6 @@ func printOpusCompareQuality(t *testing.T, quality string) {
309327
310328func printConformanceMatrix (
311329 results map [conformanceKey ]conformanceResult ,
312- vectorSets []string ,
313330 rates []int ,
314331 channelCounts []int ,
315332 vectors []string ,
@@ -318,36 +335,33 @@ func printConformanceMatrix(
318335 return
319336 }
320337
321- fmt .Println ("RFC 6716 / 8251 conformation matrix" )
338+ fmt .Println ("Opus conformance matrix" )
322339 fmt .Println ("Legend: numeric cells are opus_compare quality percentages; FAIL means the vector did not pass." )
340+ fmt .Println ("Inputs use the shared RFC 6716 / RFC 8251 bitstream corpus; accepted references follow RFC 8251 Section 11." )
323341
324- for _ , vectorSet := range vectorSets {
325- fmt .Printf ("\n vector set: %s\n " , vectorSet )
326- printConformanceMatrixRule (vectors )
327- fmt .Printf ("| %-8s | %-2s |" , "rate" , "ch" )
328- for _ , vector := range vectors {
329- fmt .Printf (" %-*s |" , conformanceMatrixVectorCellWidth , vector )
330- }
331- fmt .Println ()
332- printConformanceMatrixRule (vectors )
333-
334- for _ , rate := range rates {
335- for _ , channels := range channelCounts {
336- fmt .Printf ("| %-8d | %-2d |" , rate , channels )
337- for _ , vector := range vectors {
338- key := conformanceKey {
339- vectorSet : vectorSet ,
340- rate : rate ,
341- channels : channels ,
342- vector : vector ,
343- }
344- fmt .Printf (" %-*s |" , conformanceMatrixVectorCellWidth , conformanceMatrixCell (results , key ))
342+ printConformanceMatrixRule (vectors )
343+ fmt .Printf ("| %-8s | %-2s |" , "rate" , "ch" )
344+ for _ , vector := range vectors {
345+ fmt .Printf (" %-*s |" , conformanceMatrixVectorCellWidth , vector )
346+ }
347+ fmt .Println ()
348+ printConformanceMatrixRule (vectors )
349+
350+ for _ , rate := range rates {
351+ for _ , channels := range channelCounts {
352+ fmt .Printf ("| %-8d | %-2d |" , rate , channels )
353+ for _ , vector := range vectors {
354+ key := conformanceKey {
355+ rate : rate ,
356+ channels : channels ,
357+ vector : vector ,
345358 }
346- fmt .Println ( )
359+ fmt .Printf ( " %-*s |" , conformanceMatrixVectorCellWidth , conformanceMatrixCell ( results , key ) )
347360 }
361+ fmt .Println ()
348362 }
349- printConformanceMatrixRule (vectors )
350363 }
364+ printConformanceMatrixRule (vectors )
351365}
352366
353367const conformanceMatrixVectorCellWidth = 5
@@ -364,7 +378,6 @@ func writeConformanceMarkdown(
364378 t * testing.T ,
365379 path string ,
366380 results map [conformanceKey ]conformanceResult ,
367- vectorSets []string ,
368381 rates []int ,
369382 channelCounts []int ,
370383 vectors []string ,
@@ -377,35 +390,32 @@ func writeConformanceMarkdown(
377390
378391 var b strings.Builder
379392 b .WriteString ("Legend: numeric cells are `opus_compare` quality percentages; `FAIL` means the vector did not pass.\n \n " )
380- for _ , vectorSet := range vectorSets {
381- fmt .Fprintf (& b , "### %s\n \n " , vectorSet )
382- b .WriteString ("| rate | ch |" )
383- for _ , vector := range vectors {
384- fmt .Fprintf (& b , " %s |" , vector )
385- }
386- b .WriteString ("\n | --- | --- |" )
387- for range vectors {
388- b .WriteString (" --- |" )
389- }
390- b .WriteString ("\n " )
391-
392- for _ , rate := range rates {
393- for _ , channels := range channelCounts {
394- fmt .Fprintf (& b , "| %d | %d |" , rate , channels )
395- for _ , vector := range vectors {
396- key := conformanceKey {
397- vectorSet : vectorSet ,
398- rate : rate ,
399- channels : channels ,
400- vector : vector ,
401- }
402- fmt .Fprintf (& b , " %s |" , conformanceMatrixCell (results , key ))
393+ b .WriteString ("Inputs use the shared RFC 6716 / RFC 8251 bitstream corpus; accepted references follow RFC 8251 Section 11.\n \n " )
394+ b .WriteString ("| rate | ch |" )
395+ for _ , vector := range vectors {
396+ fmt .Fprintf (& b , " %s |" , vector )
397+ }
398+ b .WriteString ("\n | --- | --- |" )
399+ for range vectors {
400+ b .WriteString (" --- |" )
401+ }
402+ b .WriteString ("\n " )
403+
404+ for _ , rate := range rates {
405+ for _ , channels := range channelCounts {
406+ fmt .Fprintf (& b , "| %d | %d |" , rate , channels )
407+ for _ , vector := range vectors {
408+ key := conformanceKey {
409+ rate : rate ,
410+ channels : channels ,
411+ vector : vector ,
403412 }
404- b . WriteString ( " \n " )
413+ fmt . Fprintf ( & b , " %s |" , conformanceMatrixCell ( results , key ) )
405414 }
415+ b .WriteString ("\n " )
406416 }
407- b .WriteString ("\n " )
408417 }
418+ b .WriteString ("\n " )
409419
410420 if err := os .WriteFile (path , []byte (b .String ()), 0o600 ); err != nil {
411421 t .Fatalf ("write conformance markdown: %v" , err )
@@ -428,7 +438,16 @@ func conformanceMatrixCell(results map[conformanceKey]conformanceResult, key con
428438}
429439
430440func conformanceFinalRange (d * Decoder ) (uint32 , error ) {
431- return d .silkDecoder .FinalRange (), nil
441+ switch d .previousMode {
442+ case configurationModeCELTOnly :
443+ return d .celtDecoder .FinalRange (), nil
444+ case configurationModeSilkOnly :
445+ return d .rangeFinal , nil
446+ case configurationModeHybrid :
447+ return d .rangeFinal , nil
448+ default :
449+ return 0 , fmt .Errorf ("unsupported final range mode: %s" , d .previousMode )
450+ }
432451}
433452
434453func conformancePacketSamplesPerChannel (packet []byte , rate int ) (int , error ) {
0 commit comments