1 /**
2     \file  ADM_audioWriteAAC
3     \brief Write AAC packets inside ADTS container
4     copyright            : (C) 2016 by mean
5     email                : fixounet@free.fr
6  ***************************************************************************/
7 
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 
17 #include "ADM_default.h"
18 #include "ADM_audioStream.h"
19 #include "ADM_audioWriteAAC.h"
20 
21 /**
22  */
23 static 	int aacSampleRate[16]=
24 {
25 	96000, 88200, 64000, 48000,
26 	44100, 32000, 24000, 22050,
27 	16000, 12000, 11025,  8000,
28 	0,     0,     0,     0
29 };
30 /**
31  * \fn frequency2index
32  * @param frequency
33  * @return
34  */
frequency2index(int frequency)35 int frequency2index(int frequency)
36 {
37 
38     int dex=0;
39     while(aacSampleRate[dex])
40     {
41         if(aacSampleRate[dex]==frequency)
42             return dex;
43         dex++;
44     }
45     return -1;
46 
47 }
48 
49 /**
50     \fn ctor
51 */
ADM_audioWriteAAC()52 ADM_audioWriteAAC::ADM_audioWriteAAC()
53 {
54 
55 }
56 /**
57     \fn writeHeader
58 */
writeHeader(ADM_audioStream * stream)59 bool ADM_audioWriteAAC::writeHeader(ADM_audioStream *stream)
60 {
61 
62           return true;
63 }
64 
65 
66 /**
67     \fn close
68 */
69 
close(void)70 bool ADM_audioWriteAAC::close(void)
71 {
72     return ADM_audioWrite::close();
73 }
74 /**
75     \fn init
76     \brief write wavHeader
77 */
78 
init(ADM_audioStream * stream,const char * fileName)79 bool ADM_audioWriteAAC::init(ADM_audioStream *stream, const char *fileName)
80 {
81     WAVHeader *hdr=stream->getInfo();
82     if(hdr->encoding!=WAV_AAC)
83     {
84         ADM_warning("Not AAC!\n");
85         return false;
86     }
87     int samplingFrequencyIndex=frequency2index(hdr->frequency);
88     if(samplingFrequencyIndex==-1)
89     {
90         ADM_warning("Invalid frequency \n");
91         return false;
92     }
93     uint32_t l;
94     uint8_t *d;
95     int profileMinus1=0;
96     if(stream->getExtraData(&l,&d))
97     {
98         if(l>0)
99         {
100             profileMinus1=d[0]>>3;
101             if(profileMinus1)
102                 profileMinus1--;
103             ADM_info("AAC profile minus 1= %d\n",profileMinus1);
104             int fqIdxFromConfig=((d[0]&7)<<1)+(d[1]>>7);
105             if(fqIdxFromConfig<13 && samplingFrequencyIndex!=fqIdxFromConfig) // explicit frequency not handled
106             {
107                 ADM_warning("Using frequency index from extradata = %d (header says %d).\n",fqIdxFromConfig,samplingFrequencyIndex);
108                 samplingFrequencyIndex=fqIdxFromConfig;
109             }
110         }else
111             ADM_warning("No valid AAC extra data");
112     }else
113     {
114         ADM_warning("Cannot get profile!\n");
115     }
116 
117 
118     int channel=hdr->channels;
119 
120     aacHeader[0]=0xff;
121     aacHeader[1]=0xf1;
122     aacHeader[2]=(profileMinus1<<6);
123     aacHeader[2]|=(samplingFrequencyIndex)<<2;
124     aacHeader[2]|=channel>>2;
125     aacHeader[3]=(channel&3)<<6; // Channel configuration+frameLength
126     aacHeader[4]=0; // frame length
127     aacHeader[5]=0; // frame length + buffer fullness
128     aacHeader[6]=0; // buffer fullness  + only one frame
129 
130     if(false==ADM_audioWrite::init(stream,fileName)) return false;
131     return true;
132 }
133 
134 
135 /**
136  * \fn write
137  * \brief incoming is one packet
138 */
write(uint32_t size,uint8_t * buffer)139 bool ADM_audioWriteAAC::write(uint32_t size, uint8_t *buffer)
140 {
141     int totalLength=size+7;
142       // update header
143       aacHeader[3]&=0xc0;
144       aacHeader[3]|=totalLength>>11;
145       aacHeader[4]=totalLength>>3;
146       aacHeader[5]=(totalLength&7)<<5;
147       // Buffer fullness
148       fwrite(aacHeader,7,1,_file);
149       return ADM_audioWrite::write(size,buffer);
150 }
151 
152 //EOF
153