From bb8f2368d97de80b9c4a4c771592a9cb19bf99f2 Mon Sep 17 00:00:00 2001 From: Tom Callaway Date: Tue, 30 Jul 2019 17:24:36 -0400 Subject: [PATCH] more glue --- SnackMpg.c | 810 +++++++++++++++++++++++++++++++++ snack2.2.10-mpg123.patch | 164 +++++++ snack2.2.10-nomp3.patch | 160 ------- snack2.2.10-seektell-fix.patch | 12 + snack2.2.10-shared-stubs.patch | 16 +- tcl-snack.spec | 35 +- 6 files changed, 1017 insertions(+), 180 deletions(-) create mode 100755 SnackMpg.c create mode 100644 snack2.2.10-mpg123.patch delete mode 100644 snack2.2.10-nomp3.patch create mode 100644 snack2.2.10-seektell-fix.patch diff --git a/SnackMpg.c b/SnackMpg.c new file mode 100755 index 0000000..ced876b --- /dev/null +++ b/SnackMpg.c @@ -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 +#include +#include "snack.h" +#include +#include +#include "mpg123.h" + +#if defined(__WIN32__) +# include +# include +# define WIN32_LEAN_AND_MEAN +# include +# 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 + +/* #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 = (len0) { + 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); +} diff --git a/snack2.2.10-mpg123.patch b/snack2.2.10-mpg123.patch new file mode 100644 index 0000000..0821e48 --- /dev/null +++ b/snack2.2.10-mpg123.patch @@ -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 "Mono" o + be read -- not all of them can be written.) +
    +
  • "WAV"
  • +-
  • "MP3"
  • +
  • "AU"
  • +
  • "SND"
  • +
  • "AIFF"
  • +@@ -381,7 +380,7 @@ operation + +

    read (filename)

    + 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 fileformat=RAW. In this case, properties of + the sound data can be specified by hand, using the 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 @@ +   + +
    +-Standard extension packages (sound, snackogg, snacksphere)
    ++Standard extension packages (sound, snackogg, snackmpg, snacksphere) + +
    +  
    +@@ -650,7 +650,7 @@ fmt?
    ?-rate f? ?-channels n? ?-en + endianess? ?-start start? ?-end end? ?-guessproperties boolean? + ?-progress callback? +
      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 "-fileformat + RAW". In this case the properties of the +@@ -1064,6 +1064,8 @@ description on how to use the -progre +
        The sound package gives you the snack::audio, snack::filter, snack::mixer, and snack::sound commands. Basicly the same functions as the snack package except for graphics. This is useful on some systems if you want to use the tclsh interpreter.
      +

      snackogg +

        The snackogg 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 -fileformat ogg. When creating Ogg files the additional options -nominalbitrate, -maxbitrate, -minbitrate, and -comment apply.
      ++

      snackmpg ++

        The snackmpg 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: -author, -album, -title, -year, -tag, -genre, -played, -remain.
      +

      snacksphere +

        The snacksphere package adds support for reading the NIST/Sphere sound file formats. Sphere files are detected automatically.
      +

      +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]] diff --git a/snack2.2.10-nomp3.patch b/snack2.2.10-nomp3.patch deleted file mode 100644 index 04fd66c..0000000 --- a/snack2.2.10-nomp3.patch +++ /dev/null @@ -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 "Mono" o - be read -- not all of them can be written.) -

        -
      • "WAV"
      • --
      • "MP3"
      • -+
      • "MP3" (MP3 support is disabled in Fedora releases)
      • -
      • "AU"
      • -
      • "SND"
      • -
      • "AIFF"
      • -@@ -381,7 +381,7 @@ operation - -

        read (filename)

        - 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 fileformat=RAW. In this case, properties of - the sound data can be specified by hand, using the 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; diff --git a/snack2.2.10-seektell-fix.patch b/snack2.2.10-seektell-fix.patch new file mode 100644 index 0000000..3519b12 --- /dev/null +++ b/snack2.2.10-seektell-fix.patch @@ -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 diff --git a/snack2.2.10-shared-stubs.patch b/snack2.2.10-shared-stubs.patch index a03550d..77d1e42 100644 --- a/snack2.2.10-shared-stubs.patch +++ b/snack2.2.10-shared-stubs.patch @@ -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 diff --git a/tcl-snack.spec b/tcl-snack.spec index 4546ed7..378399f 100644 --- a/tcl-snack.spec +++ b/tcl-snack.spec @@ -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 - 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 - 2.2.10-40 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild