libsndfile source files.
[Faustine.git] / interpretor / libsndfile-1.0.25 / src / broadcast.c
diff --git a/interpretor/libsndfile-1.0.25/src/broadcast.c b/interpretor/libsndfile-1.0.25/src/broadcast.c
new file mode 100644 (file)
index 0000000..975ee84
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+** Copyright (C) 2006-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "common.h"
+
+
+static int gen_coding_history (char * added_history, int added_history_max, const SF_INFO * psfinfo) ;
+
+static inline size_t
+bc_min_size (const SF_BROADCAST_INFO* info)
+{      if (info == NULL)
+               return 0 ;
+
+       return offsetof (SF_BROADCAST_INFO, coding_history) + info->coding_history_size ;
+} /* bc_min_size */
+
+SF_BROADCAST_INFO_16K*
+broadcast_var_alloc (void)
+{      return calloc (1, sizeof (SF_BROADCAST_INFO_16K)) ;
+} /* broadcast_var_alloc */
+
+int
+broadcast_var_set (SF_PRIVATE *psf, const SF_BROADCAST_INFO * info, size_t datasize)
+{      size_t len ;
+
+       if (info == NULL)
+               return SF_FALSE ;
+
+       if (bc_min_size (info) > datasize)
+       {       psf->error = SFE_BAD_BROADCAST_INFO_SIZE ;
+               return SF_FALSE ;
+               } ;
+
+       if (datasize >= sizeof (SF_BROADCAST_INFO_16K))
+       {       psf->error = SFE_BAD_BROADCAST_INFO_TOO_BIG ;
+               return SF_FALSE ;
+               } ;
+
+       if (psf->broadcast_16k == NULL)
+       {       if ((psf->broadcast_16k = broadcast_var_alloc ()) == NULL)
+               {       psf->error = SFE_MALLOC_FAILED   ;
+                       return SF_FALSE ;
+                       } ;
+               } ;
+
+       memcpy (psf->broadcast_16k, info, offsetof (SF_BROADCAST_INFO, coding_history)) ;
+
+       psf_strlcpy_crlf (psf->broadcast_16k->coding_history, info->coding_history, sizeof (psf->broadcast_16k->coding_history), datasize - offsetof (SF_BROADCAST_INFO, coding_history)) ;
+       len = strlen (psf->broadcast_16k->coding_history) ;
+
+       if (len > 0 && psf->broadcast_16k->coding_history [len - 1] != '\n')
+               psf_strlcat (psf->broadcast_16k->coding_history, sizeof (psf->broadcast_16k->coding_history), "\r\n") ;
+
+       if (psf->file.mode == SFM_WRITE)
+       {       char added_history [256] ;
+
+               gen_coding_history (added_history, sizeof (added_history), &(psf->sf)) ;
+               psf_strlcat (psf->broadcast_16k->coding_history, sizeof (psf->broadcast_16k->coding_history), added_history) ;
+               } ;
+
+       /* Force coding_history_size to be even. */
+       len = strlen (psf->broadcast_16k->coding_history) ;
+       len += (len & 1) ? 1 : 2 ;
+       psf->broadcast_16k->coding_history_size = len ;
+
+       /* Currently writing this version. */
+       psf->broadcast_16k->version = 1 ;
+
+       return SF_TRUE ;
+} /* broadcast_var_set */
+
+
+int
+broadcast_var_get (SF_PRIVATE *psf, SF_BROADCAST_INFO * data, size_t datasize)
+{      size_t size ;
+
+       if (psf->broadcast_16k == NULL)
+               return SF_FALSE ;
+
+       size = SF_MIN (datasize, bc_min_size ((const SF_BROADCAST_INFO *) psf->broadcast_16k)) ;
+
+       memcpy (data, psf->broadcast_16k, size) ;
+
+       return SF_TRUE ;
+} /* broadcast_var_get */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+gen_coding_history (char * added_history, int added_history_max, const SF_INFO * psfinfo)
+{      char chnstr [16] ;
+       int count, width ;
+
+       /*
+       **      From : http://www.sr.se/utveckling/tu/bwf/docs/codhist2.htm
+       **
+       **      Parameter            Variable string <allowed option>                 Unit
+       **      ==========================================================================================
+       **      Coding Algorithm     A=<ANALOGUE, PCM, MPEG1L1, MPEG1L2, MPEG1L3,
+       **                           MPEG2L1, MPEG2L2, MPEG2L3>
+       **      Sampling frequency   F=<11000,22050,24000,32000,44100,48000>          [Hz]
+       **      Bit-rate             B=<any bit-rate allowed in MPEG 2 (ISO/IEC       [kbit/s per channel]
+       **                           13818-3)>
+       **      Word Length          W=<8, 12, 14, 16, 18, 20, 22, 24>                [bits]
+       **      Mode                 M=<mono, stereo, dual-mono, joint-stereo>
+       **      Text, free string    T=<a free ASCII-text string for in house use.
+       **                           This string should contain no commas (ASCII
+       **                           2Chex). Examples of the contents: ID-No; codec
+       **                           type; A/D type>
+       */
+
+       switch (psfinfo->channels)
+       {       case 0 :
+                       return SF_FALSE ;
+
+               case 1 :
+                       psf_strlcpy (chnstr, sizeof (chnstr), "mono") ;
+                       break ;
+
+               case 2 :
+                       psf_strlcpy (chnstr, sizeof (chnstr), "stereo") ;
+                       break ;
+
+               default :
+                       snprintf (chnstr, sizeof (chnstr), "%uchn", psfinfo->channels) ;
+                       break ;
+               } ;
+
+       switch (SF_CODEC (psfinfo->format))
+       {       case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_S8 :
+                       width = 8 ;
+                       break ;
+               case SF_FORMAT_PCM_16 :
+                       width = 16 ;
+                       break ;
+               case SF_FORMAT_PCM_24 :
+                       width = 24 ;
+                       break ;
+               case SF_FORMAT_PCM_32 :
+                       width = 32 ;
+                       break ;
+               case SF_FORMAT_FLOAT :
+                       width = 24 ; /* Bits in the mantissa + 1 */
+                       break ;
+               case SF_FORMAT_DOUBLE :
+                       width = 53 ; /* Bits in the mantissa + 1 */
+                       break ;
+               case SF_FORMAT_ULAW :
+               case SF_FORMAT_ALAW :
+                       width = 12 ;
+                       break ;
+               default :
+                       width = 42 ;
+                       break ;
+               } ;
+
+       count = snprintf (added_history, added_history_max,
+                                                       "A=PCM,F=%u,W=%hu,M=%s,T=%s-%s\r\n",
+                                                       psfinfo->samplerate, width, chnstr, PACKAGE, VERSION) ;
+
+       if (count >= added_history_max)
+               return 0 ;
+
+       return count ;
+} /* gen_coding_history */
+