Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration and sample links #26

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ if (MINGW)
target_link_libraries(sf3convert
${QT_LIBRARIES}
vorbis
##vorbisfile
vorbisenc
vorbisfile
ogg
sndfile-1
)
Expand All @@ -52,6 +53,8 @@ if (MINGW)
${CROSS}/lib/libsndfile-1.dll
${CROSS}/lib/libogg.dll
${CROSS}/lib/libvorbis.dll
${CROSS}/lib/libvorbisenc.dll
${CROSS}/lib/libvorbisfile.dll
${CROSSQT}/bin/Qt5Core.dll
${CROSSQT}/bin/Qt5Xml.dll
${CROSSQT}/bin/icuin51.dll
Expand Down Expand Up @@ -82,6 +85,28 @@ else (MINGW)
message("libvorbis not found\n")
endif (VORBIS_INCDIR)

##
## libvorbisenc
##

PKGCONFIG1 (vorbisenc 1.3.3 VORBISENC_INCDIR VORBISENC_LIBDIR VORBISENC_LIB VORBISENC_CPP)
if (VORBISENC_INCDIR)
message("libvorbisenc detected ${VORBISENC_INCDIR} ${VORBISENC_LIBDIR} ${VORBISENC_LIB}")
else (VORBISENC_INCDIR)
message("libvorbisenc not found\n")
endif (VORBISENC_INCDIR)

##
## libvorbisfile
##

PKGCONFIG1 (vorbisfile 1.3.3 VORBISFILE_INCDIR VORBISFILE_LIBDIR VORBISFILE_LIB VORBISFILE_CPP)
if (VORBISFILE_INCDIR)
message("libvorbisfile detected ${VORBISFILE_INCDIR} ${VORBISFILE_LIBDIR} ${VORBISFILE_LIB}")
else (VORBISFILE_INCDIR)
message("libvorbisfile not found\n")
endif (VORBISFILE_INCDIR)


##
## libogg
Expand All @@ -103,13 +128,16 @@ else (MINGW)
${SNDFILE_INCDIR}
${OGG_INCDIR}
${VORBIS_INCDIR}
${VORBISENC_INCDIR}
${VORBISFILE_INCDIR}
)

target_link_libraries(sf3convert
${QT_LIBRARIES}
${OGG_LIB}
${VORBIS_LIB}
vorbisenc
${VORBISENC_LIB}
${VORBISFILE_LIB}
${SNDFILE_LIB}
)

Expand Down
34 changes: 21 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
### sf3convert
# sf3convert

Utilities for SoundFont files.
Utilities for converting Soundfont files from version 2 to version 3 and back from version 3 to version 2.

* compress sound font files with ogg vorbis for use with [MuseScore](http://musescore.org)
* convert to "C" for embedding
### Sf3 format

The sf3 format stores compressed data (OGG vorbis files) instead of raw data (WAVE) in a soundfont. There is thus a **loss in quality** but the resulting files are lighter and more prone to be **embedded**. This format has been primarily designed and used by [MuseScore](http://musescore.org) and is now supported by other projects:

* [Calf-Fluidsynth](http://calf-studio-gear.org/)
* [Carla](http://kxstudio.linuxaudio.org/Applications:Carla)
* [LMMS](https://lmms.io)
* [Polyphone](https://www.polyphone-soundfonts.com)
* [Qsynth](https://qsynth.sourceforge.io)
* [Qtractor](https://qtractor.sourceforge.io)

**The compressed soundfont has the major version number 3. It is non standard and no specifications have been written yet**


### Compilation
Expand All @@ -14,21 +24,19 @@ Utilities for SoundFont files.
* libsdnfile
* libogg
* libvorbis
* libvorbisenc
* libvorbisfile

```
$ make release
```

### Usage Example:

This compresses the Fluid sound font from 148 MBytes to 20 MBytes.
### Usage example:

sf3convert -z FluidR3.SF2 mops.sf3
This compresses a soundfont from 148 MBytes to 20 MBytes.

**The compressed sound font has the major version number 3. Its non standard
and can be used only (so far) by [MuseScore](http://musescore.org).**
sf3convert -z FluidR3.sf2 compressed_soundfont.sf3

This uncompresses a soundfont

### TODO:
Stereo samples are compressed as two single streams instead of compressing
them as stereo ogg vorbis streams. This may be less optimal.
sf3convert -y compressed_soundfont.sf3 FluidR3.sf2
10 changes: 7 additions & 3 deletions sf3convert.1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
.Nd SoundFont conversion utility
.Sh SYNOPSIS
.Nm
.Op Fl cdsxz
.Op Fl cdsxyz
.Op Fl a Ar ampl
.Op Fl p Ar pres
.Op Fl S Ar number
Expand All @@ -20,7 +20,8 @@
The
.Nm
utility converts an SF2 format SoundFont; it can compress it
into SF3, encode as C for embedding into a binary, or as XML.
into SF3, uncompress it from SF3, encode as C for embedding into a binary,
or as XML.
.Pp
The options are as follows:
.Bl -tag -width xxx
Expand Down Expand Up @@ -49,13 +50,16 @@ as the OGG stream serial number instead of a time-based random one.
Create a small soundfont (one instrument/preset), pan to 0.
.It Fl x
Output XML.
.It Fl y
Uncompress the soundfont.
.It Fl z
Compress the soundfont.
.El
.Pp
The
.Fl c ,
.Fl d
.Fl d ,
.Fl y
and
.Fl z
options are mutually exclusive.
Expand Down
42 changes: 32 additions & 10 deletions sfconvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,37 @@
#include <QtCore/QTime>
#include "sfont.h"

bool smallSf = false;

//---------------------------------------------------------
// usage
//---------------------------------------------------------

static void usage(const char* pname)
{
{
fprintf(stderr, "usage: %s [-flags] soundfont [outfile]\n", pname);
fprintf(stderr, " -z compress sf\n");
fprintf(stderr, " -q qq ogg quality\n");
fprintf(stderr, " -a nn amplification in dB before ogg compression\n");
fprintf(stderr, " -y uncompress sf\n");
fprintf(stderr, " -x xml output\n");
fprintf(stderr, " -c c output\n");
fprintf(stderr, " -p nn preset\n");
fprintf(stderr, " -d dump presets\n");
fprintf(stderr, " -s create small sf (one instrument/preset), pan to 0\n");
fprintf(stderr, " -S nn ogg serial number\n");
}
}

//---------------------------------------------------------
// main
//---------------------------------------------------------

int main(int argc, char* argv[])
{
{
bool xml = false;
bool code = false;
bool dump = false;
bool compress = false;
bool uncompress = false;
bool smallSf = false;
double oggQuality = 0.3;
double oggAmp = -1.0;
qint64 oggSerial = std::numeric_limits<qint64>::max();
Expand All @@ -67,7 +68,7 @@ int main(int argc, char* argv[])
fprintf(stderr, "%s: convert sound file\n", argv[0]);

int c;
while ((c = getopt(argc, argv, "xcp:dS:szq:a:")) != EOF) {
while ((c = getopt(argc, argv, "xcp:dS:syzq:a:")) != EOF) {
switch(c) {
case 'x':
xml = true;
Expand All @@ -87,6 +88,9 @@ int main(int argc, char* argv[])
case 's':
smallSf = true;
break;
case 'y':
uncompress = true;
break;
case 'z':
compress = true;
break;
Expand All @@ -113,12 +117,18 @@ int main(int argc, char* argv[])
usage(pname);
exit(3);
}
if (!xml && !code && !dump && !compress) {
if (!xml && !code && !dump && !compress && !uncompress) {
usage(pname);
exit(4);
}
if (compress && uncompress) {
usage(pname);
exit(5);
}

SoundFont sf(argv[0]);
SfTools::SoundFont sf(argv[0]);
if (smallSf)
sf.smallSf = true;

if (!sf.read()) {
fprintf(stderr, "sf read error\n");
Expand All @@ -142,10 +152,22 @@ int main(int argc, char* argv[])
if (xml)
sf.writeXml(&fo);
else
sf.write(&fo, oggQuality, oggAmp, oggSerial);
sf.compress(&fo, oggQuality, oggAmp, oggSerial);
fo.close();
}
else if (uncompress) {
QFile fo(argv[1]);
if (!fo.open(QIODevice::WriteOnly)) {
fprintf(stderr, "cannot open <%s>\n", argv[2]);
exit(2);
}
if (xml)
sf.writeXml(&fo);
else
sf.uncompress(&fo);
fo.close();
}
qDebug("Soundfont converted in: %d ms", t.elapsed());
return 0;
}
}

Loading