more glue

This commit is contained in:
Tom Callaway 2019-07-30 17:24:36 -04:00
parent de826c11d4
commit bb8f2368d9
6 changed files with 1017 additions and 180 deletions

810
SnackMpg.c Executable file
View File

@ -0,0 +1,810 @@
/*
* A Snack MP3 format handler using libmpg123.
*
* BSD Copyright 2009 - Peter MacDonald
*
* Implements mp3 as a loadable module using libmpg123 (which is LGPL).
* Replaces snacks builtin MP3 driver which:
*
* - has noise major artifacts when used with -file on 48000 sound cards.
* - fails on small mp3 files (under 20k?).
* - has a restrictive (non-commercial only) licence
* - Can't be easily removed from snack (to avoid patent issue)
*
* TODO:
* - Check if file changed on multiple opens (for header).
* - Check return codes.
* - Add encoding support option (ie. use lame library?).
*
*/
#include <math.h>
#include <tcl.h>
#include "snack.h"
#include <stdlib.h>
#include <time.h>
#include "mpg123.h"
#if defined(__WIN32__)
# include <io.h>
# include <fcntl.h>
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# undef WIN32_LEAN_AND_MEAN
# define EXPORT(a,b) __declspec(dllexport) a b
BOOL APIENTRY
DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
return TRUE;
}
#else
# define EXPORT(a,b) a b
#endif
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#include <stdio.h>
/* #define MPG_NODIRECT_FILES 1 */
/* If above is defined we never let libmpg123 use native files directly. */
#define MPG123_STRING "MPG"
#define SNACK_MPG123_INT 21
#define DECODEBUFSIZE (10*BUFSIZ)
#define READBUFSIZE 8500
typedef struct Mpg123_File {
mpg123_handle *m;
int maxbitrate;
int minbitrate;
int nombitrate;
double quality;
long rate;
int channels, enc;
mpg123_id3v1 *v1;
mpg123_id3v2 *v2;
Tcl_Obj *fname, *nfname;
struct mpg123_frameinfo fi;
int ref;
size_t savepos[10];
int lastret;
Tcl_Channel datasource;
long ttllen;
int isFile;
int noFiles;
char *chanType;
int started;
int opened;
int gotformat;
unsigned char *pcmbuf;
int buffer_size;
off_t current_frame;
off_t frames_left;
double current_seconds;
double seconds_left;
int seeksync;
} Mpg123_File;
#ifdef __cplusplus
}
#endif /* __cplusplus */
static int mpgIsInit = 0;
Mpg123_File * AllocMpg(Sound *s) {
Mpg123_File *of;
of = (Mpg123_File*) ckalloc(sizeof(Mpg123_File));
memset(of, 0, sizeof(Mpg123_File));
s->extHead2 = (char *) of;
s->extHead2Type = SNACK_MPG123_INT;
of->nombitrate = 128000;
of->maxbitrate = -1;
of->minbitrate = -1;
of->quality = -1.0;
of->seeksync = 5000;
#ifdef MPG_NODIRECT_FILES
of->noFiles = 1;
#endif
return of;
}
Mpg123_File *MpgObj(Sound *s) {
Mpg123_File *of = (Mpg123_File *)s->extHead2;
if (of == NULL) {
of = AllocMpg(s);
}
return of;
}
static int guessByMagic = 1;
/* If above is 1 GuessMpg123File() looks only at header magic alone. */
/* Meaning the header bits start with 0xFFF or the string ID3 or RIFF. */
/* This avoids the more expensive decoding first chunk to see if we have mp3. */
char *
GuessMpg123File(char *buf, int len)
{
long rate;
int channels, enc;
int fnd = 0, ret, done;
mpg123_handle *m;
unsigned char *ubuf = buf;
unsigned char pcmout[4*sizeof(short)*20000];
int decsiz = 4*sizeof(short)*20000;
if (len < 4) return(QUE_STRING);
if ((ubuf[0] == 0xff && (ubuf[1]&0xf0) == 0xf0)) {
return MPG123_STRING;
}
if (buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') {
return MPG123_STRING;
}
if (len > 20 && buf[20] == 0x55 &&
toupper(buf[0]) == 'R' && toupper(buf[0]) == 'I' &&
toupper(buf[0]) == 'F' && toupper(buf[0]) == 'F') {
return(MP3_STRING);
}
if (guessByMagic) {
return NULL;
}
if (!mpgIsInit) {
mpgIsInit = 1;
mpg123_init();
}
m = mpg123_new(NULL, &ret);
if(m == NULL)
{
fprintf(stderr, "mp3 fail\n" );
return NULL;
}
mpg123_open_feed(m);
ret = mpg123_decode(m, buf, len, pcmout, decsiz, &done);
if (ret != MPG123_ERR ) {
ret = mpg123_getformat(m, &rate, &channels, &enc);
if (channels<=0) {
ret = MPG123_ERR;
}
}
mpg123_delete(m);
if (ret != MPG123_ERR) {
return(MPG123_STRING);
}
return NULL;
}
char *
ExtMpg123File(char *s)
{
int l1 = strlen(".mp3");
int l2 = strlen(s);
if (strncasecmp(".mp3", &s[l2 - l1], l1) == 0) {
return(MPG123_STRING);
}
return(NULL);
}
static int
Mpg123Setup(Sound *s, Tcl_Interp *interp, Tcl_Channel ch)
{
mpg123_handle *m;
Mpg123_File *of;
int ret, fd, rc;
long mlen;
Tcl_ChannelType *cType;
of = MpgObj(s);
of->isFile = 0;
Tcl_SetChannelOption(interp, ch, "-translation", "binary");
#ifdef TCL_81_API
Tcl_SetChannelOption(interp, ch, "-encoding", "binary");
#endif
cType = Tcl_GetChannelType(ch);
if (of->noFiles == 0 && of->opened) {
of->isFile = !strcmp(cType->typeName, "file");
}
if (s->debug)
fprintf(stderr, "CHANTYPE(%d,%d): %s, BUF=%d\n", of->isFile, of->noFiles, cType->typeName, DECODEBUFSIZE);
if (!mpgIsInit) {
mpgIsInit = 1;
mpg123_init();
}
m = of->m;
/* TODO: check file name didn't change */
if (m != NULL) {
/* If used with */
if (of->ref<10) {
if (of->isFile){
of->savepos[of->ref] = mpg123_tell(m);
} else {
}
}
of->ref++;
}
if (of->isFile){
of->fname = Tcl_NewStringObj(s->fcname, -1);
Tcl_IncrRefCount(of->fname);
of->nfname = Tcl_FSGetNormalizedPath(interp, of->fname);
} else {
of->lastret = MPG123_NEED_MORE;
}
of->datasource = ch;
m = mpg123_new(NULL, &ret);
if(m == NULL) {
Tcl_AppendResult(interp, "Unable to create mpg123 handle: ", mpg123_plain_strerror(ret), 0);
return TCL_ERROR;
}
of->m = m;
if (of->isFile){
if (mpg123_open(m, Tcl_GetString(of->nfname)) != MPG123_OK) {
Tcl_AppendResult(interp, "Open mpg123 failed: ", mpg123_plain_strerror(ret), 0);
return TCL_ERROR;
}
if (s->debug) mpg123_param(m, MPG123_VERBOSE, 2, 0);
if (s->debug == 0 ) mpg123_param(m, MPG123_ADD_FLAGS, MPG123_QUIET, 0);
/*mpg123_param(m, MPG123_ADD_FLAGS, MPG123_SEEKBUFFER, 0);
mpg123_param(m, MPG123_ADD_FLAGS, MPG123_FUZZY, 0);
mpg123_param(m, MPG123_REMOVE_FLAGS, MPG123_GAPLESS, 0);*/
} else {
mpg123_open_feed(m);
}
if (of->pcmbuf) ckfree( of->pcmbuf );
of->buffer_size = mpg123_outblock( m );
of->pcmbuf = ckalloc( of->buffer_size );
mlen = (long)mpg123_length(m);
if (mlen<=0) {
return TCL_OK;
}
of->gotformat = 1;
Snack_SetLength(s, mlen);
mpg123_info(of->m, &of->fi);
mpg123_getformat(of->m, &of->rate, &of->channels, &of->enc);
if (s->debug) fprintf(stderr, "MPG FORMAT: channels=%d, rate=%ld enc=0x%x\n", of->channels, of->rate, of->enc);
Snack_SetSampleRate(s, of->rate);
Snack_SetNumChannels(s, of->channels);
Snack_SetSampleEncoding(s, LIN16);
of->nombitrate = of->rate;
rc = mpg123_id3(of->m, &of->v1, &of->v2);
Snack_SetBytesPerSample(s, 2);
Snack_SetHeaderSize(s, 0);
return TCL_OK;
}
static int
OpenMpg123File(Sound *s, Tcl_Interp *interp, Tcl_Channel *ch, char *mode)
{
mpg123_handle *m;
Mpg123_File *of;
int ret, fd, rc;
long mlen;
Tcl_ChannelType *cType;
if (s->debug) fprintf(stderr, "MPG Open: %p : %s\n", s, s->fcname);
*ch = Tcl_OpenFileChannel(interp, s->fcname, mode, 420);
if (*ch == NULL) {
Tcl_AppendResult(interp, "Mpg123: unable to open file: ",
Snack_GetSoundFilename(s), NULL);
return TCL_ERROR;
}
of = MpgObj(s);
of->opened = 1;
return Mpg123Setup(s, interp, *ch);
}
static int
FreeRes(Mpg123_File *of)
{
if (of->fname) {
Tcl_DecrRefCount(of->fname);
}
of->fname = NULL;
of->nfname = NULL;
of->v1 = NULL;
of->v2 = NULL;
if (of->m) {
mpg123_delete(of->m);
}
if (of->pcmbuf) {
ckfree(of->pcmbuf);
}
of->pcmbuf = NULL;
of->m = NULL;
}
static int
CloseMpg123File(Sound *s, Tcl_Interp *interp, Tcl_Channel *ch)
{
Mpg123_File *of;
of = MpgObj(s);
if (s->debug) fprintf(stderr, "MPG Close: %p\n", s);
if (of->ref > 0 && of->m) {
of->ref--;
if (of->ref<10) {
if (of->isFile){
mpg123_seek(of->m, of->savepos[of->ref], SEEK_SET);
}
}
return;
}
FreeRes(of);
if (of->started == 0) {
*ch = NULL;
} else {
of->started = 0;
}
if (ch != NULL) {
Tcl_Close(interp, *ch);
}
*ch = NULL;
return TCL_OK;
}
static int
ReadMpg123Samples(Sound *s, Tcl_Interp *interp, Tcl_Channel ch, char *ibuf,
float *obuf, int len)
{
Mpg123_File *of;
int i, iread, rc, cnt, bigendian = Snack_PlatformIsLittleEndian() ? 0 : 1;
float *f = obuf;
size_t done = 0, rlen, nread = 0;
short *r;
long bytes;
char buffer[READBUFSIZE];
of = MpgObj(s);
of->started = 1;
memset(obuf, 0, len*sizeof(float));
/*rlen = (len<DECODEBUFSIZE?len:DECODEBUFSIZE); */
while (len>0) {
rlen = (len * sizeof(short));
if (rlen>of->buffer_size) rlen = of->buffer_size;
if (of->isFile) {
rc = mpg123_read(of->m, of->pcmbuf, rlen, &done);
} else {
if (of->lastret == MPG123_NEED_MORE) {
bytes=Tcl_Read(of->datasource, buffer, READBUFSIZE);
if (bytes <= 0) {
if (s->debug) fprintf(stderr, "MPG ERR\n");
return 0;
}
rc = mpg123_decode(of->m, buffer, bytes, of->pcmbuf, rlen, &done);
} else {
rc = mpg123_decode(of->m, NULL, 0, of->pcmbuf, rlen, &done);
}
}
of->lastret = rc;
if (rc == MPG123_NEW_FORMAT || !of->gotformat) {
of->gotformat = 1;
mpg123_getformat(of->m, &of->rate, &of->channels, &of->enc);
if (s->debug) fprintf(stderr, "MPG FORMAT: channels=%d, rate=%ld enc=0x%x\n", of->channels, of->rate, of->enc);
Snack_SetSampleRate(s, of->rate);
Snack_SetNumChannels(s, of->channels);
}
if (rc == MPG123_DONE) {
if (s->debug) fprintf(stderr, "MPG DONE: %d\n", nread);
return nread;
}
if (rc == MPG123_ERR) {
if (s->debug) fprintf(stderr, "MPG ERROR: %d\n", nread);
return 0;
}
r = (short *) of->pcmbuf;
cnt = (done / sizeof(short));
for (i = 0; i < cnt; i++) {
float fv = (float)*r;
*f++ = fv;
r++;
}
nread += cnt;
if (s->debug) fprintf(stderr, "MPG READ (%d of %d): %d\n", nread, len, rc);
if (cnt >= len) break;
len -= cnt;
}
if (nread>0) {
of->ttllen += nread;
if (of->isFile == 0) {
/* Don't know length for channels so we lie. */
Snack_SetLength(s, of->ttllen+1);
}
}
if (done < 0) {
return 0;
}
if (of->isFile) {
mpg123_position(of->m, 0, nread * sizeof(short),
&of->current_frame, &of->frames_left, &of->current_seconds,
&of->seconds_left);
}
iread = (int)nread;
if (iread < 0)
iread = 1;
if (s->debug) fprintf(stderr, "MPG READ RET: %d\n", nread);
return iread;
}
/* SeekMpg123File:
*
* Seek to sound-sample position.
* This happens a lot when global rate does not equal decode rate.
* We work around quanticize bug (resyncing?)
* by seeking back an extra amount, then read forward again by that amount.
* TODO: check return codes.
*/
static int
SeekMpg123File(Sound *s, Tcl_Interp *interp, Tcl_Channel ch, int pos)
{
Mpg123_File *of;
int opos;
of = MpgObj(s);
if (s->debug) fprintf(stderr, "MPG SEEK: %d\n", pos);
if (of->started == 0 && pos == 0) {
if (s->debug) fprintf(stderr, "MPG SEEK SKIPPED\n");
return pos;
}
opos = mpg123_tell(of->m);
if (pos == opos) {
if (s->debug) fprintf(stderr, "MPG SEEK NOMOVE: %d\n", opos, pos);
}
opos = pos;
if (of->datasource) {
int extra = (pos>of->seeksync?of->seeksync:pos);
size_t done;
if (of->isFile) {
if (of->seeksync > 0 && extra > 0) {
mpg123_seek(of->m, pos-extra, SEEK_SET);
mpg123_read(of->m, of->pcmbuf, extra, &done);
} else {
mpg123_seek(of->m, pos, SEEK_SET);
}
} else {
off_t ioffs;
if (of->seeksync > 0 && extra > 0) {
mpg123_feedseek(of->m, pos-extra, SEEK_SET, &ioffs);
Tcl_Seek(of->datasource, ioffs, SEEK_SET);
Tcl_Read(of->datasource, of->pcmbuf, extra);
mpg123_decode(of->m, of->pcmbuf, extra, NULL, 0, &done);
mpg123_decode(of->m, NULL, 0, of->pcmbuf, extra, &done);
} else {
mpg123_feedseek(of->m, pos, SEEK_SET, &ioffs);
Tcl_Seek(of->datasource, ioffs, SEEK_SET);
}
}
}
pos = mpg123_tell(of->m);
if (s->debug) fprintf(stderr, "MPG SEEKPOS: %d -> %d\n", opos, pos);
if (pos<0) {
return(-1);
} else {
return pos;
}
}
static int
GetMpg123Header(Sound *s, Tcl_Interp *interp, Tcl_Channel ch, Tcl_Obj *obj,
char *buf)
{
Mpg123_File *of;
long mlen;
size_t done;
int i, ret, rc;
mpg123_id3v1 *v1; mpg123_id3v2 *v2;
of = MpgObj(s);
if (!of->opened) {
return Mpg123Setup(s, interp, ch);
}
if (s->debug) fprintf(stderr, "MPG Header\n");
/* For the case when Tcl_Open has been done somewhere else */
if (s->extHead2 != NULL && s->extHead2Type != SNACK_MPG123_INT) {
Snack_FileFormat *ff;
for (ff = Snack_GetFileFormats(); ff != NULL; ff = ff->nextPtr) {
if (strcmp(s->fileType, ff->name) == 0) {
if (ff->freeHeaderProc != NULL) {
(ff->freeHeaderProc)(s);
}
}
}
}
of = MpgObj(s);
of->started = 1;
mlen = (long)mpg123_length(of->m);
if (mlen<=0) {
return TCL_OK;
return TCL_ERROR;
}
Snack_SetLength(s, mlen);
mpg123_info(of->m, &of->fi);
mpg123_getformat(of->m, &of->rate, &of->channels, &of->enc);
if (s->debug) fprintf(stderr, "MPG FORMAT: channels=%d, rate=%ld enc=0x%x\n", of->channels, of->rate, of->enc);
Snack_SetSampleRate(s, of->rate);
Snack_SetNumChannels(s, of->channels);
Snack_SetSampleEncoding(s, LIN16);
of->nombitrate = of->rate;
rc = mpg123_id3(of->m, &of->v1, &of->v2);
Snack_SetBytesPerSample(s, 2);
Snack_SetHeaderSize(s, 0);
return TCL_OK;
}
void
FreeMpg123Header(Sound *s)
{
Mpg123_File *of = (Mpg123_File *)s->extHead2;
if (s->extHead2 != NULL) {
FreeRes(of);
ckfree((char *)s->extHead2);
s->extHead2 = NULL;
s->extHead2Type = 0;
}
}
int
ConfigMpg123(Sound *s, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
Mpg123_File *of;
int arg, index;
static CONST char *optionStrings[] = {
"-comment", "-album", "-seeksync",
"-artist", "-year", "-tag", "-title", "-genre",
"-maxbitrate", "-minbitrate", "-nominalbitrate",
"-quality", "-nofiles", "-magiconly", "-played", "-remain", NULL
};
enum options {
COMMENT, ALBUM, SEEKSYNC, ARTIST, YEAR, TAG, TITLE, GENRE, MAX, MIN, NOMINAL, QUALITY, NOFILES, USEMAGIC, SECONDS, REMAIN
};
of = MpgObj(s);
if (s->extHead2 != NULL && s->extHead2Type != SNACK_MPG123_INT) {
Snack_FileFormat *ff;
for (ff = Snack_GetFileFormats(); ff != NULL; ff = ff->nextPtr) {
if (strcmp(s->fileType, ff->name) == 0) {
if (ff->freeHeaderProc != NULL) {
(ff->freeHeaderProc)(s);
}
}
}
}
if (objc < 3) return 0;
if (objc == 3) {
/* get option */
if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings, "option", 0,
&index) != TCL_OK) {
Tcl_AppendResult(interp, ", or\n", NULL);
return 0;
}
#define NSO(str) Tcl_NewStringObj((of->v1 && of->v1->str)?(of->v1->str):"",-1)
switch ((enum options) index) {
case COMMENT:
{
Tcl_SetObjResult(interp, NSO(comment));
break;
}
case ALBUM:
{
Tcl_SetObjResult(interp, NSO(album));
break;
}
case TITLE:
{
Tcl_SetObjResult(interp, NSO(title));
break;
}
case TAG:
{
Tcl_SetObjResult(interp, NSO(tag));
break;
}
case YEAR:
{
Tcl_SetObjResult(interp, NSO(year));
break;
}
case GENRE:
{
if (of->v1)
Tcl_SetObjResult(interp, Tcl_NewIntObj(of->v1?of->v1->genre:-1));
break;
}
case NOFILES:
{
Tcl_SetObjResult(interp, Tcl_NewIntObj(of->noFiles));
break;
}
case MAX:
{
Tcl_SetObjResult(interp, Tcl_NewIntObj(of->maxbitrate));
break;
}
case MIN:
{
Tcl_SetObjResult(interp, Tcl_NewIntObj(of->minbitrate));
break;
}
case NOMINAL:
{
Tcl_SetObjResult(interp, Tcl_NewIntObj(of->nombitrate));
break;
}
case SEEKSYNC:
{
Tcl_SetObjResult(interp, Tcl_NewIntObj(of->seeksync));
break;
}
case REMAIN:
{
Tcl_SetObjResult(interp, Tcl_NewIntObj(of->seconds_left));
break;
}
case SECONDS:
{
Tcl_SetObjResult(interp, Tcl_NewIntObj(of->current_seconds));
break;
}
case QUALITY:
{
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(of->quality));
break;
}
case USEMAGIC:
{
Tcl_SetObjResult(interp, Tcl_NewIntObj(guessByMagic));
break;
}
}
} else {
/* set option */
for (arg = 2; arg < objc; arg+=2) {
int index;
if (Tcl_GetIndexFromObj(interp, objv[arg], optionStrings, "option", 0,
&index) != TCL_OK) {
return 0;
}
if (arg + 1 == objc) {
Tcl_AppendResult(interp, "No argument given for ",
optionStrings[index], " option\n", (char *) NULL);
return 0;
}
switch ((enum options) index) {
case NOFILES:
{
#ifndef MPG_NODIRECT_FILES
if (Tcl_GetIntFromObj(interp,objv[arg+1], &of->noFiles) != TCL_OK)
#endif
return 0;
break;
}
case COMMENT:
{
int i, n;
break;
}
case MAX:
{
if (Tcl_GetIntFromObj(interp,objv[arg+1], &of->maxbitrate) != TCL_OK)
return 0;
break;
}
case MIN:
{
if (Tcl_GetIntFromObj(interp,objv[arg+1], &of->minbitrate) != TCL_OK)
return 0;
break;
}
case NOMINAL:
{
if (Tcl_GetIntFromObj(interp,objv[arg+1], &of->nombitrate) != TCL_OK)
return 0;
break;
}
case SEEKSYNC:
{
if (Tcl_GetIntFromObj(interp,objv[arg+1], &of->seeksync) != TCL_OK)
return 0;
break;
}
case USEMAGIC:
{
if (Tcl_GetIntFromObj(interp,objv[arg+1], &guessByMagic) != TCL_OK)
return 0;
break;
}
case QUALITY:
{
if (Tcl_GetDoubleFromObj(interp, objv[arg+1], &of->quality) !=TCL_OK)
return 0;
break;
}
}
}
}
return 1;
}
#define MPG123FILE_VERSION "1.3"
Snack_FileFormat snackMpg123Format = {
MPG123_STRING,
GuessMpg123File,
GetMpg123Header,
ExtMpg123File,
NULL, /* PutMpg123Header, */
OpenMpg123File,
CloseMpg123File,
ReadMpg123Samples,
NULL, /* WriteMpg123Samples, */
SeekMpg123File,
FreeMpg123Header,
ConfigMpg123,
(Snack_FileFormat *) NULL
};
/* Called by "load libsnackmpg" */
EXPORT(int, Snackmpg_Init) _ANSI_ARGS_((Tcl_Interp *interp))
{
int res;
#ifdef USE_TCL_STUBS
if (Tcl_InitStubs(interp, "8", 0) == NULL) {
return TCL_ERROR;
}
#endif
#ifdef USE_SNACK_STUBS
if (Snack_InitStubs(interp, "2", 0) == NULL) {
return TCL_ERROR;
}
#endif
res = Tcl_PkgProvide(interp, "snackmpg", MPG123FILE_VERSION);
if (res != TCL_OK) return res;
Tcl_SetVar(interp, "snack::snackmpg", MPG123FILE_VERSION, TCL_GLOBAL_ONLY);
Snack_CreateFileFormat(&snackMpg123Format);
return TCL_OK;
}
EXPORT(int, Snackmpg_SafeInit)(Tcl_Interp *interp)
{
return Snackmpg_Init(interp);
}

164
snack2.2.10-mpg123.patch Normal file
View File

@ -0,0 +1,164 @@
diff -up snack2.2.10/doc/python-man.html.mpg123 snack2.2.10/doc/python-man.html
--- snack2.2.10/doc/python-man.html.mpg123 2005-12-14 06:29:39.000000000 -0500
+++ snack2.2.10/doc/python-man.html 2019-07-30 16:14:55.453593911 -0400
@@ -158,7 +158,6 @@ than or equal to 1, or <tt>"Mono"</tt> o
be read -- not all of them can be&nbsp;<emph>written</emph>.)</dd>
<ul type="">
<li> "WAV"</li>
- <li> "MP3"</li>
<li> "AU"</li>
<li> "SND"</li>
<li> "AIFF"</li>
@@ -381,7 +380,7 @@ operation</td>
<h4> read (<i>filename</i>)</h4>
Reads new sound data from a file. Current supported file formats are WAV,
-MP3, AU, SND, AIFF, SD, SMP, CSL, and RAW binary. The command returns the
+AU, SND, AIFF, SD, SMP, CSL, and RAW binary. The command returns the
file format detected. It is possible to force a file to be read as RAW using
by setting the option <b>fileformat=RAW</b>. In this case, properties of
the sound data can be specified by hand, using the <b>rate, channels, encoding,
diff -up snack2.2.10/doc/tcl-man.html.mpg123 snack2.2.10/doc/tcl-man.html
--- snack2.2.10/doc/tcl-man.html.mpg123 2005-12-14 06:29:39.000000000 -0500
+++ snack2.2.10/doc/tcl-man.html 2019-07-30 16:14:55.453593911 -0400
@@ -46,7 +46,7 @@
&nbsp;</dt>
<dt>
-<a href="#defpack">Standard extension packages</a> (sound, snackogg, snacksphere)</dt>
+<a href="#defpack">Standard extension packages</a> (sound, snackogg, snackmpg, snacksphere)</dt>
<dt>
&nbsp;</dt>
@@ -650,7 +650,7 @@ fmt?</b> <b>?-rate f? ?-channels n? ?-en
endianess? ?-start start? ?-end end?</b> <b>?-guessproperties boolean?
?-progress callback?</b>
<ul>Reads new sound data from a file. Current supported file formats are
-WAV, MP3, AU, SND, AIFF, SD, SMP, CSL, and RAW binary. The command returns
+WAV, AU, SND, AIFF, SD, SMP, CSL, and RAW binary. The command returns
the file format detected. It is possible to force a file to be read as
RAW using "<b>-fileformat
</b>RAW". In this case the properties of the
@@ -1064,6 +1064,8 @@ description on how to use the <b>-progre
<ul>The <b>sound</b> package gives you the <b>snack::audio, snack::filter, snack::mixer, </b>and <b>snack::sound </b>commands. Basicly the same functions as the <b>snack</b> package except for graphics. This is useful on some systems if you want to use the tclsh interpreter.</ul>
<p><b>snackogg</b>
<ul>The <b>snackogg</b> package adds support for the Ogg/Vorbis compressed sound file format. Ogg format files and streams are detected automatically. Encoding is supported. Simply use the extension .ogg when writing files or use the option <b>-fileformat ogg</b>. When creating Ogg files the additional options <b>-nominalbitrate</b>, <b>-maxbitrate</b>, <b>-minbitrate</b>, and <b>-comment</b> apply.</ul>
+<p><b>snackmpg</b>
+<ul>The <b>snackmpg</b> package adds support for the MP3 compressed sound file format. MP3 format files and streams are detected automatically. Encoding is not currently supported. MP3 supports the following new readonly options: <b>-author</b>, <b>-album</b>, <b>-title</b>, <b>-year</b>, <b>-tag</b>, <b>-genre</b>, <b>-played</b>, <b>-remain</b>.</ul>
<p><b>snacksphere</b>
<ul>The <b>snacksphere</b> package adds support for reading the NIST/Sphere sound file formats. Sphere files are detected automatically.</ul>
<p>
diff -up snack2.2.10/generic/jkSoundFile.c.mpg123 snack2.2.10/generic/jkSoundFile.c
--- snack2.2.10/generic/jkSoundFile.c.mpg123 2019-07-30 16:16:32.624468486 -0400
+++ snack2.2.10/generic/jkSoundFile.c 2019-07-30 16:16:48.089130226 -0400
@@ -1785,7 +1785,7 @@ PutAuHeader(Sound *s, Tcl_Interp *interp
}
#define WAVE_FORMAT_PCM 1
-#ifndef WIN
+#ifndef WAVE_FORMAT_ALAW
# define WAVE_FORMAT_IEEE_FLOAT 3
# define WAVE_FORMAT_ALAW 6
# define WAVE_FORMAT_MULAW 7
@@ -3305,6 +3305,7 @@ Snack_FileFormat snackRawFormat = {
(Snack_FileFormat *) NULL
};
+#ifdef USE_OLD_MP3
Snack_FileFormat snackMp3Format = {
MP3_STRING,
GuessMP3File,
@@ -3320,6 +3321,7 @@ Snack_FileFormat snackMp3Format = {
ConfigMP3Header,
(Snack_FileFormat *) NULL
};
+#endif
Snack_FileFormat snackSmpFormat = {
SMP_STRING,
@@ -3434,8 +3436,12 @@ SnackDefineFileFormats(Tcl_Interp *inter
*/
{
snackFileFormats = &snackWavFormat;
+#ifdef BUILTIN_MP3
snackWavFormat.nextPtr = &snackMp3Format;
snackMp3Format.nextPtr = &snackAiffFormat;
+#else
+ snackWavFormat.nextPtr = &snackAiffFormat;
+#endif
snackAiffFormat.nextPtr = &snackAuFormat;
snackAuFormat.nextPtr = &snackSmpFormat;
snackSmpFormat.nextPtr = &snackCslFormat;
@@ -3570,8 +3576,13 @@ GetSample(SnackLinkedFileInfo *infoPtr,
Snack_WriteLogInt(" Read Tries", maxt-tries);
Snack_WriteLogInt(" Read Samples", nRead);
}
+ if (tries<=0) {
+ Snack_ProgressCallback(s->cmdPtr, s->interp, "Tries exceeded", -1.0);
+ }
infoPtr->validSamples = nRead;
- memcpy(infoPtr->buffer, junkBuffer, nRead * sizeof(float));
+ if (nRead>0) {
+ memcpy(infoPtr->buffer, junkBuffer, nRead * sizeof(float));
+ }
}
if (ff->readProc == NULL) { /* unpack block */
diff -up snack2.2.10/unix/Makefile.in.mpg123 snack2.2.10/unix/Makefile.in
--- snack2.2.10/unix/Makefile.in.mpg123 2005-12-14 06:29:39.000000000 -0500
+++ snack2.2.10/unix/Makefile.in 2019-07-30 16:14:55.453593911 -0400
@@ -43,13 +43,13 @@ SHLIB_SUFFIX = @SHLIB_SUFFIX@
all: libsound${SHLIB_SUFFIX} libsnack${SHLIB_SUFFIX} @DOSTUBLIB@ @LIBNIST@ @LIBOGG@ editversion
OBJSO = sound.o jkSound.o jkSoundEngine.o jkSoundEdit.o jkSoundFile.o \
- g711.o @AOBJ@ jkFormatMP3.o jkSoundProc.o ffa.o jkPitchCmd.o \
+ g711.o @AOBJ@ jkSoundProc.o ffa.o jkPitchCmd.o \
@STUBINITOBJ@ jkAudio.o jkMixer.o shape.o jkFilter.o jkSynthesis.o \
jkFilterIIR.o jkGetF0.o sigproc.o jkFormant.o sigproc2.o
OBJSN = snack.o jkSound.o jkSoundEngine.o jkSoundEdit.o jkSoundFile.o \
jkCanvSpeg.o jkCanvWave.o jkCanvSect.o ffa.o g711.o @AOBJ@ \
- jkFormatMP3.o jkSoundProc.o jkPitchCmd.o @STUBINITOBJ@ \
+ jkSoundProc.o jkPitchCmd.o @STUBINITOBJ@ \
jkAudio.o jkMixer.o shape.o jkFilter.o jkSynthesis.o jkFilterIIR.o \
jkGetF0.o sigproc.o jkFormant.o sigproc2.o
@@ -296,12 +296,21 @@ libsnacksphere${SHLIB_SUFFIX}: ${OBJNIST
LIBOGG = @OGGLIBS@ -lc @TCL_LIB_SPEC@ -L. @SNACK_STUB_LIB_FLAG@
OBJOGG = SnackOgg.o
+LIBMPG = -lmpg123 -lc @TCL_LIB_SPEC@ -L. @SNACK_STUB_LIB_FLAG@
+OBJMPG = SnackMpg.o
+
SnackOgg.o: $(GENERIC_DIR)/SnackOgg.c
$(CC) @OGGINC@ -c $(CFLAGS) -DUSE_SNACK_STUBS $(GENERIC_DIR)/SnackOgg.c
libsnackogg${SHLIB_SUFFIX}: ${OBJOGG}
${SHLIB_LD} ${OBJOGG} ${LIBOGG} -o libsnackogg${SHLIB_SUFFIX}
+SnackMpg.o: $(GENERIC_DIR)/SnackMpg.c
+ $(CC) -c $(CFLAGS) -DUSE_SNACK_STUBS $(GENERIC_DIR)/SnackMpg.c
+
+libsnackmpg${SHLIB_SUFFIX}: ${OBJMPG}
+ ${SHLIB_LD} ${OBJMPG} ${LIBMPG} -o libsnackmpg${SHLIB_SUFFIX}
+
install:
@if [ ! -d ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION} ] ; then \
echo "Making directory ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}"; \
@@ -314,6 +323,7 @@ install:
if test -f libsnackstub${VERSION}.a; then cp -f libsnackstub${VERSION}.a ${DESTDIR}${SNACK_INSTALL_PATH}/; fi
if test -f libsnacksphere${SHLIB_SUFFIX}; then cp -f libsnacksphere${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/; fi
if test -f libsnackogg${SHLIB_SUFFIX}; then cp -f libsnackogg${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/; fi
+ if test -f libsnackmpg${SHLIB_SUFFIX}; then cp -f libsnackmpg${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/; fi
cp -f $(UNIX_DIR)/snack.tcl ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/
cp -f pkgIndex.tcl ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/
diff -up snack2.2.10/unix/pkgIndex.tcl.dll.mpg123 snack2.2.10/unix/pkgIndex.tcl.dll
--- snack2.2.10/unix/pkgIndex.tcl.dll.mpg123 2005-12-14 06:29:39.000000000 -0500
+++ snack2.2.10/unix/pkgIndex.tcl.dll 2019-07-30 16:14:55.454593890 -0400
@@ -11,3 +11,5 @@ package ifneeded sound 2.2 [list load [f
package ifneeded snacksphere 1.2 [list load [file join $dir libsnacksphere.dll]]
package ifneeded snackogg 1.3 [list load [file join $dir libsnackogg.dll]]
+
+package ifneeded snackmpg 1.3 [list load [file join $dir libsnackmpg.dll]]

View File

@ -1,160 +0,0 @@
diff -up snack2.2.10/doc/python-man.html.BAD snack2.2.10/doc/python-man.html
--- snack2.2.10/doc/python-man.html.BAD 2008-06-11 15:12:44.000000000 -0400
+++ snack2.2.10/doc/python-man.html 2008-06-11 15:13:47.000000000 -0400
@@ -158,7 +158,7 @@ than or equal to 1, or <tt>"Mono"</tt> o
be read -- not all of them can be&nbsp;<emph>written</emph>.)</dd>
<ul type="">
<li> "WAV"</li>
- <li> "MP3"</li>
+ <li> "MP3" (MP3 support is disabled in Fedora releases)</li>
<li> "AU"</li>
<li> "SND"</li>
<li> "AIFF"</li>
@@ -381,7 +381,7 @@ operation</td>
<h4> read (<i>filename</i>)</h4>
Reads new sound data from a file. Current supported file formats are WAV,
-MP3, AU, SND, AIFF, SD, SMP, CSL, and RAW binary. The command returns the
+MP3 (disabled in Fedora), AU, SND, AIFF, SD, SMP, CSL, and RAW binary. The command returns the
file format detected. It is possible to force a file to be read as RAW using
by setting the option <b>fileformat=RAW</b>. In this case, properties of
the sound data can be specified by hand, using the <b>rate, channels, encoding,
diff -up snack2.2.10/generic/jkSound.h.BAD snack2.2.10/generic/jkSound.h
--- snack2.2.10/generic/jkSound.h.BAD 2008-06-11 15:15:03.000000000 -0400
+++ snack2.2.10/generic/jkSound.h 2008-06-11 15:15:44.000000000 -0400
@@ -413,6 +413,9 @@ extern int swapCmd(Sound *s, Tcl_Interp
#define MP3_STRING "MP3"
#define CSL_STRING "CSL"
+/*
+ * MP3 code is disabled due to patents.
+ *
extern char *GuessMP3File(char *buf, int len);
extern int GetMP3Header(Sound *s, Tcl_Interp *interp, Tcl_Channel ch,
@@ -434,6 +437,8 @@ extern void FreeMP3Header(Sound *s);
extern int ConfigMP3Header(Sound *s, Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[]);
+ */
+
typedef enum {
SNACK_WIN_HAMMING,
diff -up snack2.2.10/unix/Makefile.in.BAD snack2.2.10/unix/Makefile.in
--- snack2.2.10/unix/Makefile.in.BAD 2008-06-11 15:09:59.000000000 -0400
+++ snack2.2.10/unix/Makefile.in 2008-06-11 15:10:14.000000000 -0400
@@ -43,13 +43,13 @@ SHLIB_SUFFIX = @SHLIB_SUFFIX@
all: libsound${SHLIB_SUFFIX} libsnack${SHLIB_SUFFIX} @DOSTUBLIB@ @LIBNIST@ @LIBOGG@ editversion
OBJSO = sound.o jkSound.o jkSoundEngine.o jkSoundEdit.o jkSoundFile.o \
- g711.o @AOBJ@ jkFormatMP3.o jkSoundProc.o ffa.o jkPitchCmd.o \
+ g711.o @AOBJ@ jkSoundProc.o ffa.o jkPitchCmd.o \
@STUBINITOBJ@ jkAudio.o jkMixer.o shape.o jkFilter.o jkSynthesis.o \
jkFilterIIR.o jkGetF0.o sigproc.o jkFormant.o sigproc2.o
OBJSN = snack.o jkSound.o jkSoundEngine.o jkSoundEdit.o jkSoundFile.o \
jkCanvSpeg.o jkCanvWave.o jkCanvSect.o ffa.o g711.o @AOBJ@ \
- jkFormatMP3.o jkSoundProc.o jkPitchCmd.o @STUBINITOBJ@ \
+ jkSoundProc.o jkPitchCmd.o @STUBINITOBJ@ \
jkAudio.o jkMixer.o shape.o jkFilter.o jkSynthesis.o jkFilterIIR.o \
jkGetF0.o sigproc.o jkFormant.o sigproc2.o
@@ -73,9 +73,6 @@ jkSoundFile.o: $(GENERIC_DIR)/jkSoundFil
g711.o: $(GENERIC_DIR)/g711.c
$(CC) -c $(CFLAGS) $(GENERIC_DIR)/g711.c
-jkFormatMP3.o: $(GENERIC_DIR)/jkFormatMP3.c
- $(CC) -c $(CFLAGS) $(GENERIC_DIR)/jkFormatMP3.c
-
jkSoundProc.o: $(GENERIC_DIR)/jkSoundProc.c
$(CC) -c $(CFLAGS) $(GENERIC_DIR)/jkSoundProc.c
diff -up snack2.2.10/unix/snack.tcl.BAD snack2.2.10/unix/snack.tcl
--- snack2.2.10/unix/snack.tcl.BAD 2008-06-11 15:10:44.000000000 -0400
+++ snack2.2.10/unix/snack.tcl 2008-06-11 15:11:26.000000000 -0400
@@ -216,7 +216,7 @@ namespace eval snack {
if {$::tcl_platform(platform) == "windows"} {
set l [concat {{{MS Wav Files} {.wav}} {{Smp Files} {.smp}} {{Snd Files} {.snd}} {{AU Files} {.au}} {{AIFF Files} {.aif}} {{AIFF Files} {.aiff}} {{Waves Files} {.sd}} {{MP3 Files} {.mp3}} {{CSL Files} {.nsp}}} $loadTypes {{{All Files} * }}]
} else {
- set l [concat {{{MS Wav Files} {.wav .WAV}} {{Smp Files} {.smp .SMP}} {{Snd Files} {.snd .SND}} {{AU Files} {.au .AU}} {{AIFF Files} {.aif .AIF}} {{AIFF Files} {.aiff .AIFF}} {{Waves Files} {.sd .SD}} {{MP3 Files} {.mp3 .MP3}} {{CSL Files} {.nsp .NSP}}} $loadTypes {{{All Files} * }}]
+ set l [concat {{{MS Wav Files} {.wav .WAV}} {{Smp Files} {.smp .SMP}} {{Snd Files} {.snd .SND}} {{AU Files} {.au .AU}} {{AIFF Files} {.aif .AIF}} {{AIFF Files} {.aiff .AIFF}} {{Waves Files} {.sd .SD}} {{CSL Files} {.nsp .NSP}}} $loadTypes {{{All Files} * }}]
}
return [swapListElem $l $filebox(l$fmt)]
}
@@ -229,7 +229,6 @@ namespace eval snack {
set filebox(SD) .sd
set filebox(SND) .snd
set filebox(AIFF) .aif
- set filebox(MP3) .mp3
set filebox(CSL) .nsp
set filebox(lWAV) 0
@@ -239,7 +238,7 @@ namespace eval snack {
set filebox(lAIFF) 4
# skip 2 because of aif and aiff
set filebox(lSD) 6
- set filebox(lMP3) 7
+ # skip 1 because of mp3
set filebox(lCSL) 8
set filebox(lRAW) end
# Do not forget to update indexes
@@ -350,7 +349,6 @@ namespace eval snack {
set filebox(.sd) SD
set filebox(.aif) AIFF
set filebox(.aiff) AIFF
- set filebox(.mp3) MP3
set filebox(.nsp) CSL
set filebox() WAV
diff -up snack2.2.10/generic/jkSoundFile.c.BAD snack2.2.10/generic/jkSoundFile.c
--- snack2.2.10/generic/jkSoundFile.c.BAD 2008-06-11 15:22:35.000000000 -0400
+++ snack2.2.10/generic/jkSoundFile.c 2008-06-11 15:24:16.000000000 -0400
@@ -35,9 +35,11 @@ GuessWavFile(char *buf, int len)
{
if (len < 21) return(QUE_STRING);
if (strncasecmp("RIFF", buf, strlen("RIFF")) == 0) {
+/*
if (buf[20] == 85) {
return(MP3_STRING);
}
+*/
if (strncasecmp("WAVE", &buf[8], strlen("WAVE")) == 0) {
return(WAV_STRING);
}
@@ -3305,6 +3307,8 @@ Snack_FileFormat snackRawFormat = {
(Snack_FileFormat *) NULL
};
+/*
+
Snack_FileFormat snackMp3Format = {
MP3_STRING,
GuessMP3File,
@@ -3321,6 +3325,8 @@ Snack_FileFormat snackMp3Format = {
(Snack_FileFormat *) NULL
};
+*/
+
Snack_FileFormat snackSmpFormat = {
SMP_STRING,
GuessSmpFile,
@@ -3427,15 +3433,13 @@ SnackDefineFileFormats(Tcl_Interp *inter
snackAuFormat.nextPtr = &snackSmpFormat;
snackSmpFormat.nextPtr = &snackCslFormat;
snackCslFormat.nextPtr = &snackSdFormat;
- snackSdFormat.nextPtr = &snackMp3Format;
- snackMp3Format.nextPtr = &snackRawFormat;
+ snackSdFormat.nextPtr = &snackRawFormat;
snackRawFormat.nextPtr = NULL;
}
*/
{
snackFileFormats = &snackWavFormat;
- snackWavFormat.nextPtr = &snackMp3Format;
- snackMp3Format.nextPtr = &snackAiffFormat;
+ snackWavFormat.nextPtr = &snackAiffFormat;
snackAiffFormat.nextPtr = &snackAuFormat;
snackAuFormat.nextPtr = &snackSmpFormat;
snackSmpFormat.nextPtr = &snackCslFormat;

View File

@ -0,0 +1,12 @@
diff -up snack2.2.10/generic/jkSound.h.seektell snack2.2.10/generic/jkSound.h
--- snack2.2.10/generic/jkSound.h.seektell 2019-07-30 16:01:37.310992628 -0400
+++ snack2.2.10/generic/jkSound.h 2019-07-30 16:02:29.859840865 -0400
@@ -603,7 +603,7 @@ extern void Snack_RemoveOptions(int objc
extern void SnackPauseAudio();
-#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 4
+#if 1 || TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 4
#define TCL_SEEK Tcl_Seek
#define TCL_TELL Tcl_Tell
#else

View File

@ -1,7 +1,7 @@
diff -up snack2.2.10/unix/configure.shared-stubs snack2.2.10/unix/configure
--- snack2.2.10/unix/configure.shared-stubs 2008-06-11 16:33:05.000000000 -0400
+++ snack2.2.10/unix/configure 2008-06-11 16:33:33.000000000 -0400
@@ -1663,7 +1663,7 @@ echo "${ECHO_T}will use stubs (normal)"
--- snack2.2.10/unix/configure.shared-stubs 2005-12-14 06:29:39.000000000 -0500
+++ snack2.2.10/unix/configure 2019-07-30 15:47:04.892177200 -0400
@@ -1663,7 +1663,7 @@ echo "${ECHO_T}will use stubs (normal)"
TCL_LIB_SPEC="${TCL_STUB_LIB_SPEC}"
TK_LIB_SPEC="${TK_STUB_LIB_SPEC}"
STUBINITOBJ="snackStubInit.o"
@ -11,9 +11,9 @@ diff -up snack2.2.10/unix/configure.shared-stubs snack2.2.10/unix/configure
if test "$TCLVER" = "8.0"; then
{ echo "$as_me:$LINENO: WARNING: \"You probably forgot to specify --disable-stubs\"" >&5
diff -up snack2.2.10/unix/Makefile.in.shared-stubs snack2.2.10/unix/Makefile.in
--- snack2.2.10/unix/Makefile.in.shared-stubs 2008-06-11 16:29:57.000000000 -0400
+++ snack2.2.10/unix/Makefile.in 2008-06-11 16:32:36.000000000 -0400
@@ -164,8 +164,9 @@ libsnack${SHLIB_SUFFIX}: ${OBJSN}
--- snack2.2.10/unix/Makefile.in.shared-stubs 2019-07-30 15:47:04.891177222 -0400
+++ snack2.2.10/unix/Makefile.in 2019-07-30 15:48:21.464486362 -0400
@@ -167,8 +167,9 @@ libsnack${SHLIB_SUFFIX}: ${OBJSN}
${SHLIB_LD} ${OBJSN} ${LIBSN} -o libsnack${SHLIB_SUFFIX}
sed s/.dll/${SHLIB_SUFFIX}/ < $(UNIX_DIR)/pkgIndex.tcl.dll > pkgIndex.tcl
@ -25,7 +25,7 @@ diff -up snack2.2.10/unix/Makefile.in.shared-stubs snack2.2.10/unix/Makefile.in
editversion: ${OBJSN}
if test "$(TCL_VERSION)" != "8.4"; then\
@@ -310,7 +311,7 @@ install:
@@ -322,7 +323,7 @@ install:
fi;
cp -f libsound${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/
cp -f libsnack${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/
@ -33,4 +33,4 @@ diff -up snack2.2.10/unix/Makefile.in.shared-stubs snack2.2.10/unix/Makefile.in
+ if test -f libsnackstub${VERSION}${SHLIB_SUFFIX}; then cp -f libsnackstub${VERSION}${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/; fi
if test -f libsnacksphere${SHLIB_SUFFIX}; then cp -f libsnacksphere${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/; fi
if test -f libsnackogg${SHLIB_SUFFIX}; then cp -f libsnackogg${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/; fi
cp -f $(UNIX_DIR)/snack.tcl ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/
if test -f libsnackmpg${SHLIB_SUFFIX}; then cp -f libsnackmpg${SHLIB_SUFFIX} ${DESTDIR}${SNACK_INSTALL_PATH}/snack${VERSION}/; fi

View File

@ -8,36 +8,38 @@
Name: tcl-%{realname}
Version: 2.2.10
Release: 40%{?dist}
Release: 41%{?dist}
Summary: Sound toolkit
# generic/snackDecls.h, generic/snackStubInit.c and generic/snackStubLib.c
# are under the TCL "license.terms", a copy of which can be found in the tcl package.
License: GPLv2+ and TCL
License: GPLv2+ and TCL and BSD
URL: http://www.speech.kth.se/snack/
# The upstream source has two files which implement MP3 decoding.
# ./generic/jkFormatMP3.c and ./generic/jkFormatMP3.h
# Due to patent concerns, we cannot ship that code, thus, the modified tarball.
# Those files are not present in the tarball, all other related removals is done
# with a patch.
# Those files are non-free so we cannot ship that code, thus, the modified tarball.
# We implement MP3 support the same way that Debian does (libsnackmpg)
# Also, mac/snack.mcp.sit.hqx is a mysterious old compressed file with no clear license.
# It is removed.
# Upstream source can be found here: http://www.speech.kth.se/snack/dist/snack2.2.10.tar.gz
Source0: %{realname}%{version}-nomp3.tar.gz
# License confirmation email for generic/ffa.c
Source1: LICENSE-ffa.c.txt
Patch0: snack2.2.10-nomp3.patch
# Copied from debian sources
Source2: SnackMpg.c
Patch0: snack2.2.10-mpg123.patch
Patch1: snack2.2.10-extracflags.patch
Patch2: snack2.2.10-shared-stubs.patch
Patch3: snack2.2.10-newALSA.patch
Patch4: tcl-snack-2.2.10-CVE-2012-6303-fix.patch
Patch5: snack2.2.10-format-security.patch
# Credit to Sergei Golovan, patch taken from Debian
# Credit to Sergei Golovan, patches taken from Debian
Patch6: tcl-snack-2.2.10-python3.patch
Patch7: snack2.2.10-seektell-fix.patch
BuildRequires: gcc-c++
BuildRequires: tcl-devel, tk-devel, libogg-devel, libvorbis-devel
BuildRequires: libXft-devel
BuildRequires: alsa-lib-devel
BuildRequires: python3-devel
BuildRequires: mpg123-devel
Requires: tcl(abi) = %{tcl_version}
Provides: %{realname} = %{version}-%{release}
@ -75,14 +77,15 @@ Tkinter are also required to use Snack.
%prep
%setup -q -n %{realname}%{version}
%patch0 -p1 -b .nomp3
%patch0 -p1 -b .mpg123
%patch1 -p1 -b .extracflags
%patch2 -p1 -b .shared-stubs
%patch3 -p1 -b .newALSA
%patch4 -p1 -b .CVE20126303
%patch5 -p1 -b .format-security
%patch6 -p1 -b .py3
%patch7 -p1 -b .seektell
cp %{SOURCE1} .
cp %{SOURCE2} generic/
chmod -x generic/*.c generic/*.h unix/*.c COPYING README demos/python/*
iconv -f iso-8859-1 -t utf-8 -o README{.utf8,}
mv README{.utf8,}
@ -91,7 +94,7 @@ sed -i -e 's|\r||g' demos/python/*.txt
%build
cd unix/
%configure --disable-static --with-tcl=%{_libdir} --with-tk=%{_libdir} --with-ogg-include=%{_includedir} --with-ogg-lib=%{_libdir} --enable-alsa
make %{?_smp_mflags} EXTRACFLAGS="%{optflags}"
make %{?_smp_mflags} EXTRACFLAGS="%{optflags}" stublib all libsnackogg.so libsnackmpg.so
cd ../python
%{__python3} setup.py build
@ -113,16 +116,19 @@ mkdir -p %{buildroot}%{_includedir}
install -p generic/*.h %{buildroot}%{_includedir}
install -p unix/snackConfig.sh %{buildroot}%{_libdir}
%filter_from_requires /libsnackstub2.2.so/d
%ldconfig_scriptlets
%files
%doc README
%license COPYING LICENSE-ffa.c.txt
%{_libdir}/libsnackstub2.2.so
%{tcl_sitearch}/%{realname}2.2/
# %%{_libdir}/libsnackstub*.so
%files devel
%{_includedir}/*.h
%{_libdir}/libsnackstub2.2.a
%{_libdir}/snackConfig.sh
%files -n python3-%{realname}
@ -131,6 +137,11 @@ install -p unix/snackConfig.sh %{buildroot}%{_libdir}
%{python3_sitelib}/__pycache__/tkSnack*
%changelog
* Tue Jul 30 2019 Tom Callaway <spot@fedoraproject.org> - 2.2.10-41
- enable mp3 support the same way debian does
- fix issue where code tries to use old seektell
- disable sharedstubs, it does not work
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.10-40
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild