2 ** Copyright (C) 2006-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published by
7 ** the Free Software Foundation; either version 2.1 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU Lesser General Public License for more details.
15 ** You should have received a copy of the GNU Lesser General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 static int gen_coding_history (char * added_history
, int added_history_max
, const SF_INFO
* psfinfo
) ;
32 bc_min_size (const SF_BROADCAST_INFO
* info
)
36 return offsetof (SF_BROADCAST_INFO
, coding_history
) + info
->coding_history_size
;
39 SF_BROADCAST_INFO_16K
*
40 broadcast_var_alloc (void)
41 { return calloc (1, sizeof (SF_BROADCAST_INFO_16K
)) ;
42 } /* broadcast_var_alloc */
45 broadcast_var_set (SF_PRIVATE
*psf
, const SF_BROADCAST_INFO
* info
, size_t datasize
)
51 if (bc_min_size (info
) > datasize
)
52 { psf
->error
= SFE_BAD_BROADCAST_INFO_SIZE
;
56 if (datasize
>= sizeof (SF_BROADCAST_INFO_16K
))
57 { psf
->error
= SFE_BAD_BROADCAST_INFO_TOO_BIG
;
61 if (psf
->broadcast_16k
== NULL
)
62 { if ((psf
->broadcast_16k
= broadcast_var_alloc ()) == NULL
)
63 { psf
->error
= SFE_MALLOC_FAILED
;
68 memcpy (psf
->broadcast_16k
, info
, offsetof (SF_BROADCAST_INFO
, coding_history
)) ;
70 psf_strlcpy_crlf (psf
->broadcast_16k
->coding_history
, info
->coding_history
, sizeof (psf
->broadcast_16k
->coding_history
), datasize
- offsetof (SF_BROADCAST_INFO
, coding_history
)) ;
71 len
= strlen (psf
->broadcast_16k
->coding_history
) ;
73 if (len
> 0 && psf
->broadcast_16k
->coding_history
[len
- 1] != '\n')
74 psf_strlcat (psf
->broadcast_16k
->coding_history
, sizeof (psf
->broadcast_16k
->coding_history
), "\r\n") ;
76 if (psf
->file
.mode
== SFM_WRITE
)
77 { char added_history
[256] ;
79 gen_coding_history (added_history
, sizeof (added_history
), &(psf
->sf
)) ;
80 psf_strlcat (psf
->broadcast_16k
->coding_history
, sizeof (psf
->broadcast_16k
->coding_history
), added_history
) ;
83 /* Force coding_history_size to be even. */
84 len
= strlen (psf
->broadcast_16k
->coding_history
) ;
85 len
+= (len
& 1) ? 1 : 2 ;
86 psf
->broadcast_16k
->coding_history_size
= len
;
88 /* Currently writing this version. */
89 psf
->broadcast_16k
->version
= 1 ;
92 } /* broadcast_var_set */
96 broadcast_var_get (SF_PRIVATE
*psf
, SF_BROADCAST_INFO
* data
, size_t datasize
)
99 if (psf
->broadcast_16k
== NULL
)
102 size
= SF_MIN (datasize
, bc_min_size ((const SF_BROADCAST_INFO
*) psf
->broadcast_16k
)) ;
104 memcpy (data
, psf
->broadcast_16k
, size
) ;
107 } /* broadcast_var_get */
109 /*------------------------------------------------------------------------------
113 gen_coding_history (char * added_history
, int added_history_max
, const SF_INFO
* psfinfo
)
118 ** From : http://www.sr.se/utveckling/tu/bwf/docs/codhist2.htm
120 ** Parameter Variable string <allowed option> Unit
121 ** ==========================================================================================
122 ** Coding Algorithm A=<ANALOGUE, PCM, MPEG1L1, MPEG1L2, MPEG1L3,
123 ** MPEG2L1, MPEG2L2, MPEG2L3>
124 ** Sampling frequency F=<11000,22050,24000,32000,44100,48000> [Hz]
125 ** Bit-rate B=<any bit-rate allowed in MPEG 2 (ISO/IEC [kbit/s per channel]
127 ** Word Length W=<8, 12, 14, 16, 18, 20, 22, 24> [bits]
128 ** Mode M=<mono, stereo, dual-mono, joint-stereo>
129 ** Text, free string T=<a free ASCII-text string for in house use.
130 ** This string should contain no commas (ASCII
131 ** 2Chex). Examples of the contents: ID-No; codec
135 switch (psfinfo
->channels
)
140 psf_strlcpy (chnstr
, sizeof (chnstr
), "mono") ;
144 psf_strlcpy (chnstr
, sizeof (chnstr
), "stereo") ;
148 snprintf (chnstr
, sizeof (chnstr
), "%uchn", psfinfo
->channels
) ;
152 switch (SF_CODEC (psfinfo
->format
))
153 { case SF_FORMAT_PCM_U8
:
154 case SF_FORMAT_PCM_S8
:
157 case SF_FORMAT_PCM_16
:
160 case SF_FORMAT_PCM_24
:
163 case SF_FORMAT_PCM_32
:
166 case SF_FORMAT_FLOAT
:
167 width
= 24 ; /* Bits in the mantissa + 1 */
169 case SF_FORMAT_DOUBLE
:
170 width
= 53 ; /* Bits in the mantissa + 1 */
172 case SF_FORMAT_ULAW
:
173 case SF_FORMAT_ALAW
:
181 count
= snprintf (added_history
, added_history_max
,
182 "A=PCM,F=%u,W=%hu,M=%s,T=%s-%s\r\n",
183 psfinfo
->samplerate
, width
, chnstr
, PACKAGE
, VERSION
) ;
185 if (count
>= added_history_max
)
189 } /* gen_coding_history */