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