[xiph-commits] r18678 - trunk/squishyball

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Sun Oct 28 00:46:28 PDT 2012


Author: xiphmont
Date: 2012-10-28 00:46:27 -0700 (Sun, 28 Oct 2012)
New Revision: 18678

Modified:
   trunk/squishyball/configure.ac
   trunk/squishyball/loader.c
   trunk/squishyball/main.c
   trunk/squishyball/squishyball.1
Log:
Add opusfile (and so Opus) support to squishyball



Modified: trunk/squishyball/configure.ac
===================================================================
--- trunk/squishyball/configure.ac	2012-10-28 01:33:37 UTC (rev 18677)
+++ trunk/squishyball/configure.ac	2012-10-28 07:46:27 UTC (rev 18678)
@@ -13,6 +13,7 @@
 
 # Checks for libraries.
 
+PKG_CHECK_MODULES([opusfile], [opusfile])
 PKG_CHECK_MODULES([vorbisfile], [vorbisfile])
 PKG_CHECK_MODULES([FLAC], [flac >= 0.8.0])
 PKG_CHECK_MODULES([ao], [ao > 1.0.0])
@@ -25,6 +26,7 @@
 AC_HEADER_STDC
 AC_CHECK_HEADERS([stdlib.h string.h])
 AC_CHECK_HEADERS([vorbis/vorbisfile.h])
+AC_CHECK_HEADERS([opus/opusfile.h])
 AC_CHECK_HEADERS([ao/ao.h])
 AC_CHECK_HEADERS([FLAC/stream_decoder.h])
 
@@ -74,11 +76,11 @@
         esac
 fi
 
-COMMON_FLAGS="$cflags_save $vorbisfile_CFLAGS $ao_CFLAGS $FLAC_CFLAGS -DUSE_FKEYSF=$USE_FKEYSF"
+COMMON_FLAGS="$cflags_save $vorbisfile_CFLAGS $opusfile_CFLAGS $ao_CFLAGS $FLAC_CFLAGS -DUSE_FKEYSF=$USE_FKEYSF"
 CFLAGS="$CFLAGS -DVERSION='\"$VERSION\"' $COMMON_FLAGS"
 DEBUG="$DEBUG -DVERSION='\\\"$VERSION\\\"' $COMMON_FLAGS"
 PROFILE="$PROFILE -DVERSION='\\\"$VERSION\\\"' $COMMON_FLAGS"
-LIBS="$LIBS $vorbisfile_LIBS $ao_LIBS $FLAC_LIBS"
+LIBS="$LIBS $vorbisfile_LIBS $opusfile_LIBS $ao_LIBS $FLAC_LIBS"
 AC_SUBST(DEBUG)
 AC_SUBST(PROFILE)
 

Modified: trunk/squishyball/loader.c
===================================================================
--- trunk/squishyball/loader.c	2012-10-28 01:33:37 UTC (rev 18677)
+++ trunk/squishyball/loader.c	2012-10-28 07:46:27 UTC (rev 18678)
@@ -2,7 +2,7 @@
  *
  *  squishyball
  *
- *      Copyright (C) 2010 Xiph.Org
+ *      Copyright (C) 2010-2012 Xiph.Org
  *
  *  squishyball is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
 #include <math.h>
 #include <errno.h>
 #include <vorbis/vorbisfile.h>
+#include <opus/opusfile.h>
 #include <FLAC/stream_decoder.h>
 #include <unistd.h>
 #include "main.h"
@@ -115,6 +116,11 @@
     memcmp (buf+28, "\x01vorbis", 7) == 0;
 }
 
+static int opus_id(char *path,unsigned char *buf){
+  return memcmp(buf, "OggS", 4) == 0 &&
+    memcmp (buf+28, "OpusHead", 8) == 0;
+}
+
 static int sw_id(char *path,unsigned char *buf){
   /* if all else fails, look for JM's favorite extension */
   return memcmp(path+strlen(path)-3,".sw",3)==0;
@@ -1009,7 +1015,157 @@
   return NULL;
 }
 
-#define MAX_ID_LEN 35
+/* Opus load support **************************************************************************/
+
+int opc_read(void *_stream,unsigned char *_ptr,int _nbytes){
+  return fread(_ptr,1,_nbytes,_stream);
+}
+
+int opc_seek(void *_stream,opus_int64 _offset,int _whence){
+  return fseek(_stream,_offset,_whence);
+}
+
+opus_int64 opc_tell(void *_stream){
+  return ftell(_stream);
+}
+
+int opc_close(void *_stream){
+  return 0;
+}
+
+static OpusFileCallbacks opus_callbacks =
+  { opc_read,opc_seek,opc_tell,opc_close };
+
+static pcm_t *opus_load(char *path, FILE *in){
+  OggOpusFile *of;
+  pcm_t *pcm=NULL;
+  off_t fill=0;
+  int throttle=0;
+  int last_section=-1;
+  int i,j;
+
+  if(fseek(in,0,SEEK_SET)==-1){
+    fprintf(stderr,"%s: Failed to seek\n",path);
+    goto err;
+  }
+
+  of = op_open_callbacks(in, &opus_callbacks , NULL, 0, NULL);
+  if(!of){
+    fprintf(stderr,"Input does not appear to be an Opus bitstream.\n");
+    goto err;
+  }
+
+  pcm = calloc(1,sizeof(pcm_t));
+  pcm->name=strdup(trim_path(path));
+  pcm->bits=-32;
+  pcm->ch=op_channel_count(of,-1);
+  pcm->rate=48000;
+  pcm->size=op_pcm_total(of,-1)*pcm->ch*4;
+  pcm->data=calloc(pcm->size,1);
+
+
+  switch(pcm->ch){
+  case 1:
+    pcm->matrix = strdup("M");
+    break;
+  case 2:
+    pcm->matrix = strdup("L,R");
+    break;
+  case 3:
+    pcm->matrix = strdup("L,C,R");
+    break;
+  case 4:
+    pcm->matrix = strdup("L,R,BL,BR");
+    break;
+  case 5:
+    pcm->matrix = strdup("L,C,R,BL,BR");
+    break;
+  case 6:
+    pcm->matrix = strdup("L,C,R,BL,BR,LFE");
+    break;
+  case 7:
+    pcm->matrix = strdup("L,C,R,SL,SR,BC,LFE");
+    break;
+  default:
+    pcm->matrix = strdup("L,C,R,SL,SR,BL,BR,LFE");
+    break;
+  }
+
+  while(fill<pcm->size){
+    int current_section;
+    int i,j;
+    float pcmout[4096];
+    long ret=op_read_float(of,pcmout,4096,&current_section);
+    unsigned char *d = pcm->data+fill;
+    float *s = pcmout;
+
+    if(current_section!=last_section){
+      last_section=current_section;
+      if(op_channel_count(of,-1) != pcm->ch){
+        fprintf(stderr,"%s: Chained file changes channel count\n",path);
+        goto err;
+      }
+    }
+
+    if(ret<0){
+      fprintf(stderr,"%s: Error while decoding file\n",path);
+      goto err;
+    }
+    if(ret==0){
+      fprintf(stderr,"%s: Audio data ended prematurely\n",path);
+      goto err;
+    }
+
+    if(sizeof(float)==4){
+      /* Assuming IEEE754, which is pedantically incorrect */
+      union {
+        float f;
+        unsigned char c[4];
+      } m;
+      if(host_is_big_endian()){
+        for(i=0;i<ret;i++){
+          for(j=0;j<pcm->ch;j++){
+            m.f=*s++;
+            d[0] = m.c[3];
+            d[1] = m.c[2];
+            d[2] = m.c[1];
+            d[3] = m.c[0];
+            d+=4;
+          }
+        }
+      }else{
+        for(i=0;i<ret;i++){
+          for(j=0;j<pcm->ch;j++){
+            m.f=*s++;
+            d[0] = m.c[0];
+            d[1] = m.c[1];
+            d[2] = m.c[2];
+            d[3] = m.c[3];
+            d+=4;
+          }
+        }
+      }
+    }else{
+      fprintf(stderr,"Unhandled case: sizeof(float)!=4\n");
+      exit(10);
+    }
+    fill += ret*pcm->ch*4;
+    if (sb_verbose && (throttle&0x3f)==0)
+      fprintf(stderr,"\rLoading %s: %ld to go...       ",pcm->name,(long)(pcm->size-fill));
+    throttle++;
+  }
+  op_free(of);
+
+  if(sb_verbose)
+    fprintf(stderr,"\r%s: loaded.                 \n",path);
+  return pcm;
+ err:
+  op_free(of);
+  free_pcm(pcm);
+  return NULL;
+}
+
+#define MAX_ID_LEN 36
 unsigned char buf[MAX_ID_LEN];
 
 /* Define the supported formats here */
@@ -1019,6 +1175,7 @@
   {flac_id,    flac_load,   "flac"},
   {oggflac_id, oggflac_load,"oggflac"},
   {vorbis_id,  vorbis_load, "oggvorbis"},
+  {opus_id,  opus_load,     "oggopus"},
   {sw_id,      sw_load,     "sw"},
   {NULL,       NULL,        NULL}
 };

Modified: trunk/squishyball/main.c
===================================================================
--- trunk/squishyball/main.c	2012-10-28 01:33:37 UTC (rev 18677)
+++ trunk/squishyball/main.c	2012-10-28 07:46:27 UTC (rev 18678)
@@ -2,7 +2,7 @@
  *
  *  squishyball
  *
- *      Copyright (C) 2010 Xiph.Org
+ *      Copyright (C) 2010-2012 Xiph.Org
  *
  *  squishyball is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -96,9 +96,9 @@
           "                           to 16-bit for playback on output\n"
           "                           devices that do not support 24-bit\n"
           "                           playback. Currently only affects\n"
-          "                           Vorbis playback; all other files\n"
-          "                           a dithered by default during down-\n"
-          "                           conversion.\n"
+          "                           Vorbis and Opus playback; all other\n"
+          "                           files are dithered by default during\n"
+          "                           down-\n conversion.\n"
           "  -e --end-time <time>   : Set sample end time for playback\n"
           "  -g --gabbagabbahey     : Display a running trials score along\n"
           "                           with indicating if each trial choice\n"
@@ -152,6 +152,7 @@
           "  FLAC and OggFLAC : 16- and 24-bit\n"
           "  SW               : mono signed 16-bit little endian raw\n"
           "  OggVorbis        : all Vorbis I files\n"
+          "  OggOpus          : all Opus files\n"
           "\n"
           ,VERSION);
 }

Modified: trunk/squishyball/squishyball.1
===================================================================
--- trunk/squishyball/squishyball.1	2012-10-28 01:33:37 UTC (rev 18677)
+++ trunk/squishyball/squishyball.1	2012-10-28 07:46:27 UTC (rev 18678)
@@ -1,7 +1,7 @@
 .\" Process this file with
 .\" groff -man -Tascii squishyball.1
 .\"
-.TH squishyball 1 "2010 December 1" "Xiph.Org Foundation" "Xiph Evaluation Tools"
+.TH squishyball 1 "2012 October 28" "Xiph.Org Foundation" "Xiph Evaluation Tools"
 
 .SH NAME
 squishyball \- perform sample comparison testing on the command line
@@ -80,8 +80,8 @@
 Always use dither when down-converting to 16-bit samples for playback
 on audio devices that do not support 24-bit playback. By default,
 uncompressed samples are always dithered, but lossy formats (such
-as Vorbis) are simply rounded.  See the section \fBCONVERSION AND DITHER
-\fRbelow for more details.
+as Vorbis and Opus) are simply rounded.  See the 
+section \fBCONVERSION AND DITHER \fRbelow for more details.
 .IP "\fB-e --end-time \fR[[\fIhh\fB:\fR]\fImm\fB:\fR]\fIss\fR[\fB.\fIff\fR]"
 Set sample end time for playback.
 .IP "\fB-g --gabbagabbahey \fR| \fB--score-display"
@@ -164,12 +164,14 @@
 Mono signed 16-bit little endian raw with a .sw extension
 .IP \fBOggVorbis
 all Vorbis I files
+.IP \fBOggOpus
+all Opus files
 
 .SH CONVERSION AND DITHER
 \fBsquishyball \fRloads all linear PCM file types at native bit depth.
 Uncompressed floating point files (eg, 32 bit floating point WAV) are
-converted to 24-bit integer PCM.  Ogg Vorbis files are also decoded to
-24-bit.
+converted to 24-bit integer PCM.  Opus and Ogg Vorbis files are also
+decoded to 24-bit.
 
 Files are 'reconciled' to identical channel ordering, length and
 bit-depth before playback begins so that CPU and memory resources usage
@@ -178,13 +180,14 @@
 are promoted to 24 bits. If 24-bit playback is unavailable, 24-bit samples
 are demoted to 16 bits.
 
-Floating point samples (32-bit) are not dithered when converting to 24-bit.
-24-bit and floating point (32 bit) samples are dithered using a TPDF
-when down-conversion to 16-bit is necessary.  Lossy-encoded samples (eg
-Ogg Vorbis files) are an exception; they are not dithered by default during
-down-conversion. This behavior can be overridden by \fB-D\fR,
-which forces dithering for lossy files as well.  Down-conversion
-dithering can be disabled for all input types with \fB-t\fR.
+Floating point samples (32-bit) are not dithered when converting to
+24-bit.  24-bit and floating point (32 bit) samples are dithered using
+a TPDF when down-conversion to 16-bit is necessary.  Lossy-encoded
+samples (eg Ogg Vorbis and Opus files) are an exception; they are not
+dithered by default during down-conversion. This behavior can be
+overridden by \fB-D\fR, which forces dithering for lossy files as
+well.  Down-conversion dithering can be disabled for all input types
+with \fB-t\fR.
 
 Samples are checked for clipping at load time. Floating point samples
 can be checked accurately. Integer samples are checked heuristically;
@@ -230,4 +233,4 @@
 .SH "SEE ALSO"
 
 .PP
-\fBabx-comparator\fR(1), \fBrateit\fR(1), \fBogg123\fR(1), \fBoggdec\fR(1), \fBflac\fR(1)
+\fBabx-comparator\fR(1), \fBrateit\fR(1), \fBogg123\fR(1), \fBoggdec\fR(1), \fBopusdec\fR(1), \fBflac\fR(1)



More information about the commits mailing list