1/*
2 * Copyright 2011 castLabs, Berlin
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.googlecode.mp4parser.boxes.mp4.objectdescriptors;
17
18import com.coremedia.iso.Hex;
19import com.coremedia.iso.IsoTypeWriter;
20
21import java.io.IOException;
22import java.nio.ByteBuffer;
23import java.util.Arrays;
24import java.util.HashMap;
25import java.util.Map;
26
27
28//
29//GetAudioObjectType()
30//{
31//audioObjectType; 5 uimsbf
32//if (audioObjectType == 31) {
33//audioObjectType = 32 + audioObjectTypeExt; 6 uimsbf
34//}
35//return audioObjectType;
36//}
37//AudioSpecificConfig ()
38//{
39//audioObjectType = GetAudioObjectType();
40//samplingFrequencyIndex; 4 bslbf
41//if ( samplingFrequencyIndex == 0xf ) {
42//samplingFrequency; 24 uimsbf
43//}
44//channelConfiguration; 4 bslbf
45//sbrPresentFlag = -1;
46//psPresentFlag = -1;
47//if ( audioObjectType == 5 ||
48//audioObjectType == 29 ) {
49//extensionAudioObjectType = 5;
50//sbrPresentFlag = 1;
51//if ( audioObjectType == 29 ) {
52//psPresentFlag = 1;
53//}
54//extensionSamplingFrequencyIndex; 4 uimsbf
55//if ( extensionSamplingFrequencyIndex == 0xf )
56//extensionSamplingFrequency; 24 uimsbf
57//audioObjectType = GetAudioObjectType();
58//if ( audioObjectType == 22 )
59//extensionChannelConfiguration; 4 uimsbf
60//}
61//else {
62//extensionAudioObjectType = 0;
63//}
64//switch (audioObjectType) {
65//case 1:
66//case 2:
67//case 3:
68//case 4:
69//case 6:
70//case 7:
71//case 17:
72//case 19:
73//case 20:
74//case 21:
75//case 22:
76//case 23:
77//GASpecificConfig();
78//break:
79//case 8:
80//CelpSpecificConfig();
81//break;
82//case 9:
83//HvxcSpecificConfig();
84//break:
85//case 12:
86//TTSSpecificConfig();
87//break;
88//case 13:
89//case 14:
90//case 15:
91//case 16:
92//StructuredAudioSpecificConfig();
93//break;
94//case 24:
95//ErrorResilientCelpSpecificConfig();
96//break;
97//case 25:
98//ErrorResilientHvxcSpecificConfig();
99//break;
100//case 26:
101//case 27:
102//ParametricSpecificConfig();
103//break;
104// case 28:
105//SSCSpecificConfig();
106//break;
107//case 30:
108//sacPayloadEmbedding; 1 uimsbf
109//SpatialSpecificConfig();
110//break;
111//case 32:
112//case 33:
113//case 34:
114//MPEG_1_2_SpecificConfig();
115//break;
116//case 35:
117//DSTSpecificConfig();
118//break;
119//case 36:
120//fillBits; 5 bslbf
121//ALSSpecificConfig();
122//break;
123//case 37:
124//case 38:
125//SLSSpecificConfig();
126//break;
127//case 39:
128//ELDSpecificConfig(channelConfiguration);
129//break:
130//case 40:
131//case 41:
132//SymbolicMusicSpecificConfig();
133//break;
134//default:
135///* reserved */
136//}
137//switch (audioObjectType) {
138//case 17:
139//case 19:
140//case 20:
141//case 21:
142//case 22:
143//case 23:
144//case 24:
145//case 25:
146//case 26:
147//case 27:
148//case 39:
149//epConfig; 2 bslbf
150//if ( epConfig == 2 || epConfig == 3 ) {
151//ErrorProtectionSpecificConfig();
152//}
153//if ( epConfig == 3 ) {
154//directMapping; 1 bslbf
155//if ( ! directMapping ) {
156///* tbd */
157//}
158//}
159//}
160//if ( extensionAudioObjectType != 5 && bits_to_decode() >= 16 ) {
161//syncExtensionType; 11 bslbf
162//if (syncExtensionType == 0x2b7) {
163//        extensionAudioObjectType = GetAudioObjectType();
164//if ( extensionAudioObjectType == 5 ) {
165//sbrPresentFlag; 1 uimsbf
166//if (sbrPresentFlag == 1) {
167//extensionSamplingFrequencyIndex; 4 uimsbf
168//if ( extensionSamplingFrequencyIndex == 0xf ) {
169//extensionSamplingFrequency; 24 uimsbf
170//}
171//if ( bits_to_decode() >= 12 ) {
172//syncExtensionType; 11 bslbf
173//if (syncExtesionType == 0x548) {
174//psPresentFlag; 1 uimsbf
175//}
176//}
177//}
178//}
179//if ( extensionAudioObjectType == 22 ) {
180//sbrPresentFlag; 1 uimsbf
181//if (sbrPresentFlag == 1) {
182//extensionSamplingFrequencyIndex; 4 uimsbf
183//if ( extensionSamplingFrequencyIndex == 0xf ) {
184//extensionSamplingFrequency; 24 uimsbf
185//}
186//}
187//extensionChannelConfiguration; 4 uimsbf
188//}
189//}
190//}
191//}
192//        }
193//
194// TFCodingType
195//0x0 AAC scaleable
196//0x1 BSAC
197//0x2 TwinVQ
198//0x3 AAC non scaleable (i.e. multichannel)
199//
200// class TFSpecificConfig( uint(4) samplingFrequencyIndex, uint(4) channelConfiguration ) {
201//uint(2) TFCodingType;
202//uint(1) frameLength;
203//uint(1) dependsOnCoreCoder;
204//if (dependsOnCoreCoder == 1){
205//uint(14)coreCoderDelay
206//}
207//if (TFCodingType==BSAC) {
208//uint(11) lslayer_length
209//}
210//uint (1) extensionFlag;
211//if (channelConfiguration == 0 ){
212//program_config_element();
213//}
214//if (extensionFlag==1){
215//<to be defined in mpeg4 phase 2>
216//}
217//}
218//
219//program_config_element()
220//{
221//element_instance_tag 4 uimsbf
222//profile 2 uimsbf
223//sampling_frequency_index 4 uimsbf
224//num_front_channel_elements 4 uimsbf
225//num_side_channel_elements 4 uimsbf
226//num_back_channel_elements 4 uimsbf
227// num_lfe_channel_elements 2 uimsbf
228//num_assoc_data_elements 3 uimsbf
229//num_valid_cc_elements 4 uimsbf
230//mono_mixdown_present 1 uimsbf
231//if ( mono_mixdown_present == 1 )
232//mono_mixdown_element_number 4 uimsbf
233//stereo_mixdown_present 1 uimsbf
234//if ( stereo_mixdown_present == 1 )
235//stereo_mixdown_element_number 4 uimsbf
236//matrix_mixdown_idx_present 1 uimsbf
237//if ( matrix_mixdown_idx_present == 1 ) {
238//matrix_mixdown_idx 2 uimsbf
239//pseudo_surround_enable 1 uimsbf
240//}
241//for ( i = 0; i < num_front_channel_elements; i++) {
242//front_element_is_cpe[i]; 1 bslbf
243//front_element_tag_select[i]; 4 uimsbf
244//}
245//for ( i = 0; i < num_side_channel_elements; i++) {
246//side_element_is_cpe[i]; 1 bslbf
247//side_element_tag_select[i]; 4 uimsbf
248//}
249//for ( i = 0; i < num_back_channel_elements; i++) {
250//back_element_is_cpe[i]; 1 bslbf
251//back_element_tag_select[i]; 4 uimsbf
252//}
253//for ( i = 0; i < num_lfe_channel_elements; i++)
254//lfe_element_tag_select[i]; 4 uimsbf
255//for ( i = 0; i < num_assoc_data_elements; i++)
256//assoc_data_element_tag_select[i]; 4 uimsbf
257//for ( i = 0; i < num_valid_cc_elements; i++) {
258//cc_element_is_ind_sw[i]; 1 uimsbf
259//valid_cc_element_tag_select[i]; 4 uimsbf
260//}
261//byte_alignment()
262//comment_field_bytes 8 uimsbf
263//for ( i = 0; i < comment_field_bytes; i++)
264//comment_field_data[i]; 8 uimsbf
265//}
266
267@Descriptor(tags = 0x5, objectTypeIndication = 0x40)
268public class AudioSpecificConfig extends BaseDescriptor {
269    byte[] configBytes;
270
271    public static Map<Integer, Integer> samplingFrequencyIndexMap = new HashMap<Integer, Integer>();
272    public static Map<Integer, String> audioObjectTypeMap = new HashMap<Integer, String>();
273    int audioObjectType;
274    int samplingFrequencyIndex;
275    int samplingFrequency;
276    int channelConfiguration;
277    int extensionAudioObjectType;
278    int sbrPresentFlag;
279    int psPresentFlag;
280    int extensionSamplingFrequencyIndex;
281    int extensionSamplingFrequency;
282    int extensionChannelConfiguration;
283    int sacPayloadEmbedding;
284    int fillBits;
285    int epConfig;
286    int directMapping;
287    int syncExtensionType;
288
289    //GASpecificConfig
290    int frameLengthFlag;
291    int dependsOnCoreCoder;
292    int coreCoderDelay;
293    int extensionFlag;
294    int layerNr;
295    int numOfSubFrame;
296    int layer_length;
297    int aacSectionDataResilienceFlag;
298    int aacScalefactorDataResilienceFlag;
299    int aacSpectralDataResilienceFlag;
300    int extensionFlag3;
301    boolean gaSpecificConfig;
302
303    //ParametricSpecificConfig
304    int isBaseLayer;
305    int paraMode;
306    int paraExtensionFlag;
307    int hvxcVarMode;
308    int hvxcRateMode;
309    int erHvxcExtensionFlag;
310    int var_ScalableFlag;
311    int hilnQuantMode;
312    int hilnMaxNumLine;
313    int hilnSampleRateCode;
314    int hilnFrameLength;
315    int hilnContMode;
316    int hilnEnhaLayer;
317    int hilnEnhaQuantMode;
318    boolean parametricSpecificConfig;
319
320    @Override
321    public void parseDetail(ByteBuffer bb) throws IOException {
322        ByteBuffer configBytes = bb.slice();
323        configBytes.limit(sizeOfInstance);
324        bb.position(bb.position() + sizeOfInstance);
325
326        //copy original bytes to internal array for constructing codec config strings (todo until writing of the config is supported)
327        this.configBytes = new byte[sizeOfInstance];
328        configBytes.get(this.configBytes);
329        configBytes.rewind();
330
331        BitReaderBuffer bitReaderBuffer = new BitReaderBuffer(configBytes);
332        audioObjectType = getAudioObjectType(bitReaderBuffer);
333        samplingFrequencyIndex = bitReaderBuffer.readBits(4);
334
335        if (samplingFrequencyIndex == 0xf) {
336            samplingFrequency = bitReaderBuffer.readBits(24);
337        }
338
339        channelConfiguration = bitReaderBuffer.readBits(4);
340
341        if (audioObjectType == 5 ||
342                audioObjectType == 29) {
343            extensionAudioObjectType = 5;
344            sbrPresentFlag = 1;
345            if (audioObjectType == 29) {
346                psPresentFlag = 1;
347            }
348            extensionSamplingFrequencyIndex = bitReaderBuffer.readBits(4);
349            if (extensionSamplingFrequencyIndex == 0xf)
350                extensionSamplingFrequency = bitReaderBuffer.readBits(24);
351            audioObjectType = getAudioObjectType(bitReaderBuffer);
352            if (audioObjectType == 22)
353                extensionChannelConfiguration = bitReaderBuffer.readBits(4);
354        } else {
355            extensionAudioObjectType = 0;
356        }
357
358        switch (audioObjectType) {
359            case 1:
360            case 2:
361            case 3:
362            case 4:
363            case 6:
364            case 7:
365            case 17:
366            case 19:
367            case 20:
368            case 21:
369            case 22:
370            case 23:
371                parseGaSpecificConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, bitReaderBuffer);
372                //GASpecificConfig();
373                break;
374            case 8:
375                throw new UnsupportedOperationException("can't parse CelpSpecificConfig yet");
376                //CelpSpecificConfig();
377                //break;
378            case 9:
379                throw new UnsupportedOperationException("can't parse HvxcSpecificConfig yet");
380                //HvxcSpecificConfig();
381                //break;
382            case 12:
383                throw new UnsupportedOperationException("can't parse TTSSpecificConfig yet");
384                //TTSSpecificConfig();
385                //break;
386            case 13:
387            case 14:
388            case 15:
389            case 16:
390                throw new UnsupportedOperationException("can't parse StructuredAudioSpecificConfig yet");
391                //StructuredAudioSpecificConfig();
392                //break;
393            case 24:
394                throw new UnsupportedOperationException("can't parse ErrorResilientCelpSpecificConfig yet");
395                //ErrorResilientCelpSpecificConfig();
396                //break;
397            case 25:
398                throw new UnsupportedOperationException("can't parse ErrorResilientHvxcSpecificConfig yet");
399                //ErrorResilientHvxcSpecificConfig();
400                //break;
401            case 26:
402            case 27:
403                parseParametricSpecificConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, bitReaderBuffer);
404                //ParametricSpecificConfig();
405                break;
406            case 28:
407                throw new UnsupportedOperationException("can't parse SSCSpecificConfig yet");
408                //SSCSpecificConfig();
409                //break;
410            case 30:
411                sacPayloadEmbedding = bitReaderBuffer.readBits(1);
412                throw new UnsupportedOperationException("can't parse SpatialSpecificConfig yet");
413                //SpatialSpecificConfig();
414                //break;
415            case 32:
416            case 33:
417            case 34:
418                throw new UnsupportedOperationException("can't parse MPEG_1_2_SpecificConfig yet");
419                //MPEG_1_2_SpecificConfig();
420                //break;
421            case 35:
422                throw new UnsupportedOperationException("can't parse DSTSpecificConfig yet");
423                //DSTSpecificConfig();
424                //break;
425            case 36:
426                fillBits = bitReaderBuffer.readBits(5);
427                throw new UnsupportedOperationException("can't parse ALSSpecificConfig yet");
428                //ALSSpecificConfig();
429                //break;
430            case 37:
431            case 38:
432                throw new UnsupportedOperationException("can't parse SLSSpecificConfig yet");
433                //SLSSpecificConfig();
434                //break;
435            case 39:
436                throw new UnsupportedOperationException("can't parse ELDSpecificConfig yet");
437                //ELDSpecificConfig(channelConfiguration);
438                //break;
439            case 40:
440            case 41:
441                throw new UnsupportedOperationException("can't parse SymbolicMusicSpecificConfig yet");
442                //SymbolicMusicSpecificConfig();
443                //break;
444            default:
445                /* reserved */
446        }
447
448        switch (audioObjectType) {
449            case 17:
450            case 19:
451            case 20:
452            case 21:
453            case 22:
454            case 23:
455            case 24:
456            case 25:
457            case 26:
458            case 27:
459            case 39:
460                epConfig = bitReaderBuffer.readBits(2);
461                if (epConfig == 2 || epConfig == 3) {
462                    throw new UnsupportedOperationException("can't parse ErrorProtectionSpecificConfig yet");
463                    //ErrorProtectionSpecificConfig();
464                }
465                if (epConfig == 3) {
466                    directMapping = bitReaderBuffer.readBits(1);
467                    if (directMapping == 0) {
468                        /* tbd */
469                        throw new RuntimeException("not implemented");
470                    }
471                }
472        }
473
474        if (extensionAudioObjectType != 5 && bitReaderBuffer.remainingBits() >= 16) {
475            syncExtensionType = bitReaderBuffer.readBits(11);
476            if (syncExtensionType == 0x2b7) {
477                extensionAudioObjectType = getAudioObjectType(bitReaderBuffer);
478                if (extensionAudioObjectType == 5) {
479                    sbrPresentFlag = bitReaderBuffer.readBits(1);
480                    if (sbrPresentFlag == 1) {
481                        extensionSamplingFrequencyIndex = bitReaderBuffer.readBits(4);
482                        if (extensionSamplingFrequencyIndex == 0xf) {
483                            extensionSamplingFrequency = bitReaderBuffer.readBits(24);
484                        }
485                        if (bitReaderBuffer.remainingBits() >= 12) {
486                            syncExtensionType = bitReaderBuffer.readBits(11); //10101001000
487                            if (syncExtensionType == 0x548) {
488                                psPresentFlag = bitReaderBuffer.readBits(1);
489                            }
490                        }
491                    }
492                }
493                if (extensionAudioObjectType == 22) {
494                    sbrPresentFlag = bitReaderBuffer.readBits(1);
495                    if (sbrPresentFlag == 1) {
496                        extensionSamplingFrequencyIndex = bitReaderBuffer.readBits(4);
497                        if (extensionSamplingFrequencyIndex == 0xf) {
498                            extensionSamplingFrequency = bitReaderBuffer.readBits(24);
499                        }
500                    }
501                    extensionChannelConfiguration = bitReaderBuffer.readBits(4);
502                }
503            }
504        }
505    }
506
507    private int gaSpecificConfigSize() {
508        return 0;
509    }
510
511    public int serializedSize() {
512        int out = 4;
513        if (audioObjectType == 2) {
514            out += gaSpecificConfigSize();
515        } else {
516            throw new UnsupportedOperationException("can't serialize that yet");
517        }
518        return out;
519    }
520
521    public ByteBuffer serialize() {
522        ByteBuffer out = ByteBuffer.allocate(serializedSize());
523        IsoTypeWriter.writeUInt8(out, 5);
524        IsoTypeWriter.writeUInt8(out, serializedSize() - 2);
525        BitWriterBuffer bwb = new BitWriterBuffer(out);
526        bwb.writeBits(audioObjectType, 5);
527        bwb.writeBits(samplingFrequencyIndex, 4);
528        if (samplingFrequencyIndex == 0xf) {
529            throw new UnsupportedOperationException("can't serialize that yet");
530        }
531        bwb.writeBits(channelConfiguration, 4);
532
533        // Don't support any extensions, unusual GASpecificConfig other than the default or anything...
534
535        return out;
536    }
537
538    private int getAudioObjectType(BitReaderBuffer in) throws IOException {
539        int audioObjectType = in.readBits(5);
540        if (audioObjectType == 31) {
541            audioObjectType = 32 + in.readBits(6);
542        }
543        return audioObjectType;
544    }
545
546    private void parseGaSpecificConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {
547//    GASpecificConfig (samplingFrequencyIndex,
548//            channelConfiguration,
549//            audioObjectType)
550//    {
551        frameLengthFlag = in.readBits(1);
552        dependsOnCoreCoder = in.readBits(1);
553        if (dependsOnCoreCoder == 1) {
554            coreCoderDelay = in.readBits(14);
555        }
556        extensionFlag = in.readBits(1);
557        if (channelConfiguration == 0) {
558            throw new UnsupportedOperationException("can't parse program_config_element yet");
559            //program_config_element ();
560        }
561        if ((audioObjectType == 6) || (audioObjectType == 20)) {
562            layerNr = in.readBits(3);
563        }
564        if (extensionFlag == 1) {
565            if (audioObjectType == 22) {
566                numOfSubFrame = in.readBits(5);
567                layer_length = in.readBits(11);
568            }
569            if (audioObjectType == 17 || audioObjectType == 19 ||
570                    audioObjectType == 20 || audioObjectType == 23) {
571                aacSectionDataResilienceFlag = in.readBits(1);
572                aacScalefactorDataResilienceFlag = in.readBits(1);
573                aacSpectralDataResilienceFlag = in.readBits(1);
574            }
575            extensionFlag3 = in.readBits(1);
576            if (extensionFlag3 == 1) {
577                /* tbd in version 3 */
578            }
579        }
580//    }
581        gaSpecificConfig = true;
582    }
583
584    private void parseParametricSpecificConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {
585        /*
586        ParametricSpecificConfig() {
587            isBaseLayer; 1 uimsbf
588            if (isBaseLayer) {
589                PARAconfig();
590            } else {
591                HILNenexConfig();
592            }
593        }
594        */
595        isBaseLayer = in.readBits(1);
596        if (isBaseLayer == 1) {
597            parseParaConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, in);
598        } else {
599            parseHilnEnexConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, in);
600        }
601    }
602
603    private void parseParaConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {
604        /*
605        PARAconfig()
606        {
607            PARAmode; 2 uimsbf
608            if (PARAmode != 1) {
609                ErHVXCconfig();
610            }
611            if (PARAmode != 0) {
612                HILNconfig();
613            }
614            PARAextensionFlag; 1 uimsbf
615            if (PARAextensionFlag) {
616                // to be defined in MPEG-4 Phase 3
617            }
618        }
619        */
620        paraMode = in.readBits(2);
621
622        if (paraMode != 1) {
623            parseErHvxcConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, in);
624        }
625        if (paraMode != 0) {
626            parseHilnConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, in);
627        }
628
629        paraExtensionFlag = in.readBits(1);
630        parametricSpecificConfig = true;
631    }
632
633    private void parseErHvxcConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {
634        /*
635        ErHVXCconfig()
636        {
637            HVXCvarMode; 1 uimsbf
638                HVXCrateMode; 2 uimsbf
639                extensionFlag; 1 uimsbf
640            if (extensionFlag) {
641                var_ScalableFlag; 1 uimsbf
642            }
643        }
644        */
645        hvxcVarMode = in.readBits(1);
646        hvxcRateMode = in.readBits(2);
647        erHvxcExtensionFlag = in.readBits(1);
648
649        if (erHvxcExtensionFlag == 1) {
650            var_ScalableFlag = in.readBits(1);
651        }
652    }
653
654    private void parseHilnConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {
655        /*
656        HILNconfig()
657        {
658            HILNquantMode; 1 uimsbf
659            HILNmaxNumLine; 8 uimsbf
660            HILNsampleRateCode; 4 uimsbf
661            HILNframeLength; 12 uimsbf
662            HILNcontMode; 2 uimsbf
663        }
664        */
665        hilnQuantMode = in.readBits(1);
666        hilnMaxNumLine = in.readBits(8);
667        hilnSampleRateCode = in.readBits(4);
668        hilnFrameLength = in.readBits(12);
669        hilnContMode = in.readBits(2);
670    }
671
672    private void parseHilnEnexConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {
673        /*
674        HILNenexConfig()
675        {
676            HILNenhaLayer; 1 uimsbf
677            if (HILNenhaLayer) {
678                HILNenhaQuantMode; 2 uimsbf
679            }
680        }
681        */
682        hilnEnhaLayer = in.readBits(1);
683        if (hilnEnhaLayer == 1) {
684            hilnEnhaQuantMode = in.readBits(2);
685        }
686    }
687
688    public byte[] getConfigBytes() {
689        return configBytes;
690    }
691
692    public int getAudioObjectType() {
693        return audioObjectType;
694    }
695
696    public int getExtensionAudioObjectType() {
697        return extensionAudioObjectType;
698    }
699
700    public int getSbrPresentFlag() {
701        return sbrPresentFlag;
702    }
703
704    public int getPsPresentFlag() {
705        return psPresentFlag;
706    }
707
708    public void setAudioObjectType(int audioObjectType) {
709        this.audioObjectType = audioObjectType;
710    }
711
712    public void setSamplingFrequencyIndex(int samplingFrequencyIndex) {
713        this.samplingFrequencyIndex = samplingFrequencyIndex;
714    }
715
716    public void setSamplingFrequency(int samplingFrequency) {
717        this.samplingFrequency = samplingFrequency;
718    }
719
720    public void setChannelConfiguration(int channelConfiguration) {
721        this.channelConfiguration = channelConfiguration;
722    }
723
724    @Override
725    public String toString() {
726        final StringBuilder sb = new StringBuilder();
727        sb.append("AudioSpecificConfig");
728        sb.append("{configBytes=").append(Hex.encodeHex(configBytes));
729        sb.append(", audioObjectType=").append(audioObjectType).append(" (").append(audioObjectTypeMap.get(audioObjectType)).append(")");
730        sb.append(", samplingFrequencyIndex=").append(samplingFrequencyIndex).append(" (").append(samplingFrequencyIndexMap.get(samplingFrequencyIndex)).append(")");
731        sb.append(", samplingFrequency=").append(samplingFrequency);
732        sb.append(", channelConfiguration=").append(channelConfiguration);
733        if (extensionAudioObjectType > 0) {
734            sb.append(", extensionAudioObjectType=").append(extensionAudioObjectType).append(" (").append(audioObjectTypeMap.get(extensionAudioObjectType)).append(")");
735            sb.append(", sbrPresentFlag=").append(sbrPresentFlag);
736            sb.append(", psPresentFlag=").append(psPresentFlag);
737            sb.append(", extensionSamplingFrequencyIndex=").append(extensionSamplingFrequencyIndex).append(" (").append(samplingFrequencyIndexMap.get(extensionSamplingFrequencyIndex)).append(")");
738            sb.append(", extensionSamplingFrequency=").append(extensionSamplingFrequency);
739            sb.append(", extensionChannelConfiguration=").append(extensionChannelConfiguration);
740        }
741//    sb.append(", sacPayloadEmbedding=").append(sacPayloadEmbedding);
742//    sb.append(", fillBits=").append(fillBits);
743//    sb.append(", epConfig=").append(epConfig);
744//    sb.append(", directMapping=").append(directMapping);
745        sb.append(", syncExtensionType=").append(syncExtensionType);
746        if (gaSpecificConfig) {
747            sb.append(", frameLengthFlag=").append(frameLengthFlag);
748            sb.append(", dependsOnCoreCoder=").append(dependsOnCoreCoder);
749            sb.append(", coreCoderDelay=").append(coreCoderDelay);
750            sb.append(", extensionFlag=").append(extensionFlag);
751            sb.append(", layerNr=").append(layerNr);
752            sb.append(", numOfSubFrame=").append(numOfSubFrame);
753            sb.append(", layer_length=").append(layer_length);
754            sb.append(", aacSectionDataResilienceFlag=").append(aacSectionDataResilienceFlag);
755            sb.append(", aacScalefactorDataResilienceFlag=").append(aacScalefactorDataResilienceFlag);
756            sb.append(", aacSpectralDataResilienceFlag=").append(aacSpectralDataResilienceFlag);
757            sb.append(", extensionFlag3=").append(extensionFlag3);
758        }
759        if (parametricSpecificConfig) {
760            sb.append(", isBaseLayer=").append(isBaseLayer);
761            sb.append(", paraMode=").append(paraMode);
762            sb.append(", paraExtensionFlag=").append(paraExtensionFlag);
763            sb.append(", hvxcVarMode=").append(hvxcVarMode);
764            sb.append(", hvxcRateMode=").append(hvxcRateMode);
765            sb.append(", erHvxcExtensionFlag=").append(erHvxcExtensionFlag);
766            sb.append(", var_ScalableFlag=").append(var_ScalableFlag);
767            sb.append(", hilnQuantMode=").append(hilnQuantMode);
768            sb.append(", hilnMaxNumLine=").append(hilnMaxNumLine);
769            sb.append(", hilnSampleRateCode=").append(hilnSampleRateCode);
770            sb.append(", hilnFrameLength=").append(hilnFrameLength);
771            sb.append(", hilnContMode=").append(hilnContMode);
772            sb.append(", hilnEnhaLayer=").append(hilnEnhaLayer);
773            sb.append(", hilnEnhaQuantMode=").append(hilnEnhaQuantMode);
774        }
775        sb.append('}');
776        return sb.toString();
777    }
778
779    static {
780        // sampling_frequency_index sampling frequeny
781//0x0 96000
782//0x1 88200
783//0x2 64000
784//0x3 48000
785//0x4 44100
786//0x5 32000
787//0x6 24000
788//0x7 22050
789//0x8 16000
790//0x9 12000
791//0xa 11025
792//0xb 8000
793//0xc reserved
794//0xd reserved
795//0xe reserved
796//0xf reserved
797        samplingFrequencyIndexMap.put(0x0, 96000);
798        samplingFrequencyIndexMap.put(0x1, 88200);
799        samplingFrequencyIndexMap.put(0x2, 64000);
800        samplingFrequencyIndexMap.put(0x3, 48000);
801        samplingFrequencyIndexMap.put(0x4, 44100);
802        samplingFrequencyIndexMap.put(0x5, 32000);
803        samplingFrequencyIndexMap.put(0x6, 24000);
804        samplingFrequencyIndexMap.put(0x7, 22050);
805        samplingFrequencyIndexMap.put(0x8, 16000);
806        samplingFrequencyIndexMap.put(0x9, 12000);
807        samplingFrequencyIndexMap.put(0xa, 11025);
808        samplingFrequencyIndexMap.put(0xb, 8000);
809
810        /* audioObjectType IDs
811          0 Null
812        1 AAC main X X
813        2 AAC LC X X X X X X X
814        3 AAC SSR X X
815        4 AAC LTP X X X X
816        5 SBR X X
817        6 AAC Scalable X X X X
818        7 TwinVQ X X X
819        8 CELP X X X X X X
820        9 HVXC X X X X X
821        10 (reserved)
822        11 (reserved)
823        12 TTSI X X X X X X
824        13 Main synthetic X X
825        14 Wavetable synthesis X* X*
826        15 General MIDI X* X*
827        16 Algorithmic Synthesis and Audio FX X* X*
828        17 ER AAC LC X X X
829        18 (reserved)
830        19 ER AAC LTP X X
831        20 ER AAC Scalable X X X
832        21 ER TwinVQ X X
833        22 ER BSAC X X
834        23 ER AAC LD X X X X
835        24 ER CELP X X X
836        25 ER HVXC X X
837        26 ER HILN X
838        27 ER Parametric X
839        28 SSC
840        29 PS X
841        30 MPEG Surround
842        31 (escape)
843        32 Layer-1
844        33 Layer-2
845        34 Layer-3
846        35 DST
847        36 ALS
848        37 SLS
849        38 SLS non-core
850        39 ER AAC ELD
851        40 SMR Simple
852        41 SMR Main
853        */
854        audioObjectTypeMap.put(1, "AAC main");
855        audioObjectTypeMap.put(2, "AAC LC");
856        audioObjectTypeMap.put(3, "AAC SSR");
857        audioObjectTypeMap.put(4, "AAC LTP");
858        audioObjectTypeMap.put(5, "SBR");
859        audioObjectTypeMap.put(6, "AAC Scalable");
860        audioObjectTypeMap.put(7, "TwinVQ");
861        audioObjectTypeMap.put(8, "CELP");
862        audioObjectTypeMap.put(9, "HVXC");
863        audioObjectTypeMap.put(10, "(reserved)");
864        audioObjectTypeMap.put(11, "(reserved)");
865        audioObjectTypeMap.put(12, "TTSI");
866        audioObjectTypeMap.put(13, "Main synthetic");
867        audioObjectTypeMap.put(14, "Wavetable synthesis");
868        audioObjectTypeMap.put(15, "General MIDI");
869        audioObjectTypeMap.put(16, "Algorithmic Synthesis and Audio FX");
870        audioObjectTypeMap.put(17, "ER AAC LC");
871        audioObjectTypeMap.put(18, "(reserved)");
872        audioObjectTypeMap.put(19, "ER AAC LTP");
873        audioObjectTypeMap.put(20, "ER AAC Scalable");
874        audioObjectTypeMap.put(21, "ER TwinVQ");
875        audioObjectTypeMap.put(22, "ER BSAC");
876        audioObjectTypeMap.put(23, "ER AAC LD");
877        audioObjectTypeMap.put(24, "ER CELP");
878        audioObjectTypeMap.put(25, "ER HVXC");
879        audioObjectTypeMap.put(26, "ER HILN");
880        audioObjectTypeMap.put(27, "ER Parametric");
881        audioObjectTypeMap.put(28, "SSC");
882        audioObjectTypeMap.put(29, "PS");
883        audioObjectTypeMap.put(30, "MPEG Surround");
884        audioObjectTypeMap.put(31, "(escape)");
885        audioObjectTypeMap.put(32, "Layer-1");
886        audioObjectTypeMap.put(33, "Layer-2");
887        audioObjectTypeMap.put(34, "Layer-3");
888        audioObjectTypeMap.put(35, "DST");
889        audioObjectTypeMap.put(36, "ALS");
890        audioObjectTypeMap.put(37, "SLS");
891        audioObjectTypeMap.put(38, "SLS non-core");
892        audioObjectTypeMap.put(39, "ER AAC ELD");
893        audioObjectTypeMap.put(40, "SMR Simple");
894        audioObjectTypeMap.put(41, "SMR Main");
895
896        /* profileLevelIds
897       0x00 Reserved for ISO use -
898     0x01 Main Audio Profile L1
899     0x02 Main Audio Profile L2
900     0x03 Main Audio Profile L3
901     0x04 Main Audio Profile L4
902     0x05 Scalable Audio Profile L1
903     0x06 Scalable Audio Profile L2
904     0x07 Scalable Audio Profile L3
905     0x08 Scalable Audio Profile L4
906     0x09 Speech Audio Profile L1
907     0x0A Speech Audio Profile L2
908     0x0B Synthetic Audio Profile L1
909     0x0C Synthetic Audio Profile L2
910     0x0D Synthetic Audio Profile L3
911     0x0E High Quality Audio Profile L1
912     0x0F High Quality Audio Profile L2
913     0x10 High Quality Audio Profile L3
914     0x11 High Quality Audio Profile L4
915     0x12 High Quality Audio Profile L5
916     0x13 High Quality Audio Profile L6
917     0x14 High Quality Audio Profile L7
918     0x15 High Quality Audio Profile L8
919     0x16 Low Delay Audio Profile L1
920     0x17 Low Delay Audio Profile L2
921     0x18 Low Delay Audio Profile L3
922     0x19 Low Delay Audio Profile L4
923     0x1A Low Delay Audio Profile L5
924     0x1B Low Delay Audio Profile L6
925     0x1C Low Delay Audio Profile L7
926     0x1D Low Delay Audio Profile L8
927     0x1E Natural Audio Profile L1
928     0x1F Natural Audio Profile L2
929     0x20 Natural Audio Profile L3
930     0x21 Natural Audio Profile L4
931     0x22 Mobile Audio Internetworking Profile L1
932     0x23 Mobile Audio Internetworking Profile L2
933     0x24 Mobile Audio Internetworking Profile L3
934     0x25 Mobile Audio Internetworking Profile L4
935     0x26 Mobile Audio Internetworking Profile L5
936     0x27 Mobile Audio Internetworking Profile L6
937     0x28 AAC Profile L1
938     0x29 AAC Profile L2
939     0x2A AAC Profile L4
940     0x2B AAC Profile L5
941     0x2C High Efficiency AAC Profile L2
942     0x2D High Efficiency AAC Profile L3
943     0x2E High Efficiency AAC Profile L4
944     0x2F High Efficiency AAC Profile L5
945     0x30 High Efficiency AAC v2 Profile L2
946     0x31 High Efficiency AAC v2 Profile L3
947     0x32 High Efficiency AAC v2 Profile L4
948     0x33 High Efficiency AAC v2 Profile L5
949     0x34 Low Delay AAC Profile L1
950     0x35 Baseline MPEG Surround Profile (see ISO/IEC
951     23003-1)
952     L1
953     0x36 Baseline MPEG Surround Profile (see ISO/IEC
954     23003-1)
955     L2
956     0x37 Baseline MPEG Surround Profile (see ISO/IEC
957     23003-1)
958     L3
959     0x38 Baseline MPEG Surround Profile (see ISO/IEC
960     23003-1)
961     L4
962     0c39 Baseline MPEG Surround Profile (see ISO/IEC
963     23003-1)
964     L5
965     0x3A Baseline MPEG Surround Profile (see ISO/IEC
966     23003-1)
967     L6
968     0x3B - 0x7F reserved for ISO use -
969     0x80 - 0xFD user private -
970     0xFE no audio profile specified -
971     0xFF no audio capability required -
972
973        */
974    }
975
976
977    public int getSamplingFrequency() {
978        return samplingFrequencyIndex == 0xf ? samplingFrequency : samplingFrequencyIndexMap.get(samplingFrequencyIndex);
979    }
980
981    public int getChannelConfiguration() {
982        return channelConfiguration;
983    }
984
985    @Override
986    public boolean equals(Object o) {
987        if (this == o) {
988            return true;
989        }
990        if (o == null || getClass() != o.getClass()) {
991            return false;
992        }
993
994        AudioSpecificConfig that = (AudioSpecificConfig) o;
995
996        if (aacScalefactorDataResilienceFlag != that.aacScalefactorDataResilienceFlag) {
997            return false;
998        }
999        if (aacSectionDataResilienceFlag != that.aacSectionDataResilienceFlag) {
1000            return false;
1001        }
1002        if (aacSpectralDataResilienceFlag != that.aacSpectralDataResilienceFlag) {
1003            return false;
1004        }
1005        if (audioObjectType != that.audioObjectType) {
1006            return false;
1007        }
1008        if (channelConfiguration != that.channelConfiguration) {
1009            return false;
1010        }
1011        if (coreCoderDelay != that.coreCoderDelay) {
1012            return false;
1013        }
1014        if (dependsOnCoreCoder != that.dependsOnCoreCoder) {
1015            return false;
1016        }
1017        if (directMapping != that.directMapping) {
1018            return false;
1019        }
1020        if (epConfig != that.epConfig) {
1021            return false;
1022        }
1023        if (erHvxcExtensionFlag != that.erHvxcExtensionFlag) {
1024            return false;
1025        }
1026        if (extensionAudioObjectType != that.extensionAudioObjectType) {
1027            return false;
1028        }
1029        if (extensionChannelConfiguration != that.extensionChannelConfiguration) {
1030            return false;
1031        }
1032        if (extensionFlag != that.extensionFlag) {
1033            return false;
1034        }
1035        if (extensionFlag3 != that.extensionFlag3) {
1036            return false;
1037        }
1038        if (extensionSamplingFrequency != that.extensionSamplingFrequency) {
1039            return false;
1040        }
1041        if (extensionSamplingFrequencyIndex != that.extensionSamplingFrequencyIndex) {
1042            return false;
1043        }
1044        if (fillBits != that.fillBits) {
1045            return false;
1046        }
1047        if (frameLengthFlag != that.frameLengthFlag) {
1048            return false;
1049        }
1050        if (gaSpecificConfig != that.gaSpecificConfig) {
1051            return false;
1052        }
1053        if (hilnContMode != that.hilnContMode) {
1054            return false;
1055        }
1056        if (hilnEnhaLayer != that.hilnEnhaLayer) {
1057            return false;
1058        }
1059        if (hilnEnhaQuantMode != that.hilnEnhaQuantMode) {
1060            return false;
1061        }
1062        if (hilnFrameLength != that.hilnFrameLength) {
1063            return false;
1064        }
1065        if (hilnMaxNumLine != that.hilnMaxNumLine) {
1066            return false;
1067        }
1068        if (hilnQuantMode != that.hilnQuantMode) {
1069            return false;
1070        }
1071        if (hilnSampleRateCode != that.hilnSampleRateCode) {
1072            return false;
1073        }
1074        if (hvxcRateMode != that.hvxcRateMode) {
1075            return false;
1076        }
1077        if (hvxcVarMode != that.hvxcVarMode) {
1078            return false;
1079        }
1080        if (isBaseLayer != that.isBaseLayer) {
1081            return false;
1082        }
1083        if (layerNr != that.layerNr) {
1084            return false;
1085        }
1086        if (layer_length != that.layer_length) {
1087            return false;
1088        }
1089        if (numOfSubFrame != that.numOfSubFrame) {
1090            return false;
1091        }
1092        if (paraExtensionFlag != that.paraExtensionFlag) {
1093            return false;
1094        }
1095        if (paraMode != that.paraMode) {
1096            return false;
1097        }
1098        if (parametricSpecificConfig != that.parametricSpecificConfig) {
1099            return false;
1100        }
1101        if (psPresentFlag != that.psPresentFlag) {
1102            return false;
1103        }
1104        if (sacPayloadEmbedding != that.sacPayloadEmbedding) {
1105            return false;
1106        }
1107        if (samplingFrequency != that.samplingFrequency) {
1108            return false;
1109        }
1110        if (samplingFrequencyIndex != that.samplingFrequencyIndex) {
1111            return false;
1112        }
1113        if (sbrPresentFlag != that.sbrPresentFlag) {
1114            return false;
1115        }
1116        if (syncExtensionType != that.syncExtensionType) {
1117            return false;
1118        }
1119        if (var_ScalableFlag != that.var_ScalableFlag) {
1120            return false;
1121        }
1122        if (!Arrays.equals(configBytes, that.configBytes)) {
1123            return false;
1124        }
1125
1126        return true;
1127    }
1128
1129    @Override
1130    public int hashCode() {
1131        int result = configBytes != null ? Arrays.hashCode(configBytes) : 0;
1132        result = 31 * result + audioObjectType;
1133        result = 31 * result + samplingFrequencyIndex;
1134        result = 31 * result + samplingFrequency;
1135        result = 31 * result + channelConfiguration;
1136        result = 31 * result + extensionAudioObjectType;
1137        result = 31 * result + sbrPresentFlag;
1138        result = 31 * result + psPresentFlag;
1139        result = 31 * result + extensionSamplingFrequencyIndex;
1140        result = 31 * result + extensionSamplingFrequency;
1141        result = 31 * result + extensionChannelConfiguration;
1142        result = 31 * result + sacPayloadEmbedding;
1143        result = 31 * result + fillBits;
1144        result = 31 * result + epConfig;
1145        result = 31 * result + directMapping;
1146        result = 31 * result + syncExtensionType;
1147        result = 31 * result + frameLengthFlag;
1148        result = 31 * result + dependsOnCoreCoder;
1149        result = 31 * result + coreCoderDelay;
1150        result = 31 * result + extensionFlag;
1151        result = 31 * result + layerNr;
1152        result = 31 * result + numOfSubFrame;
1153        result = 31 * result + layer_length;
1154        result = 31 * result + aacSectionDataResilienceFlag;
1155        result = 31 * result + aacScalefactorDataResilienceFlag;
1156        result = 31 * result + aacSpectralDataResilienceFlag;
1157        result = 31 * result + extensionFlag3;
1158        result = 31 * result + (gaSpecificConfig ? 1 : 0);
1159        result = 31 * result + isBaseLayer;
1160        result = 31 * result + paraMode;
1161        result = 31 * result + paraExtensionFlag;
1162        result = 31 * result + hvxcVarMode;
1163        result = 31 * result + hvxcRateMode;
1164        result = 31 * result + erHvxcExtensionFlag;
1165        result = 31 * result + var_ScalableFlag;
1166        result = 31 * result + hilnQuantMode;
1167        result = 31 * result + hilnMaxNumLine;
1168        result = 31 * result + hilnSampleRateCode;
1169        result = 31 * result + hilnFrameLength;
1170        result = 31 * result + hilnContMode;
1171        result = 31 * result + hilnEnhaLayer;
1172        result = 31 * result + hilnEnhaQuantMode;
1173        result = 31 * result + (parametricSpecificConfig ? 1 : 0);
1174        return result;
1175    }
1176}
1177