// Copyright 2014-2025 Jesper Larsson
//
// This file is part of Klipspringer, <https://klipspringer.eavadeaux.net/>
//
// Klipspringer is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// Klipspringer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
// even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with Klipspringer. If
// not, see <https://www.gnu.org/licenses/>.

package net.avadeaux.klipspringer;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import javax.sound.sampled.AudioSystem;
import java.util.ArrayList;
import net.avadeaux.klipspringer.codec.*;

/** Utility to encode a raw file into a flac of any supported output format. */
public class EncodeFile {
    public final static int defaultComprLevel = 5, defaultBitrate = 320, defaultMQuality = 2;
    public final static float defaultOQuality = 0.9f;
    public final static String[] formats;
    static {
        ArrayList<String> f = new ArrayList<String>(4);
        f.add("raw");
        f.add("wav");
        if (Library.flacSupported()) { f.add("flac"); f.add("oga"); }
        if (Library.vorbisSupported()) { f.add("ogg"); }
        if (Library.lameSupported()) { f.add("mp3"); }
        formats = f.toArray(new String[f.size()]);
    }

    public static PcmWriter fileEncoder(PcmFormat inFormat,
                                        long totalFrames,      // can be AudioSystem.NOT_SPECIFIED
                                        String outFnam,
                                        int flacComprLevel,
                                        float vorbisQuality,
                                        int mp3Bitrate,
                                        int mp3Quality)
        throws IOException
    {
        String ext = outFnam.substring(outFnam.lastIndexOf('.')+1).toLowerCase();
        if ("flac".equals(ext) || "oga".equals(ext)) {
            return FlacStream.fileEncoder(outFnam, inFormat, flacComprLevel);
        } else if ("ogg".equals(ext)) {
            return VorbisStream.fileEncoder(outFnam, inFormat, vorbisQuality);
        } else if ("mp3".equals(ext)) {
            return LameStream.fileEncoder(outFnam, inFormat, mp3Bitrate, mp3Quality);
        } else if ("raw".equals(ext)) {
            PcmFormat outFormat = Track.rawFormat(outFnam);
            if (!inFormat.matchesQuality(outFormat)) {
                throw new IllegalArgumentException("raw file name does not match input quality"
                                                   +" (suggest add \""+Track.rawParamQualityString(inFormat)+"\")");
            }
            RandomAccessFile file = new RandomAccessFile(outFnam, "rw");
            file.setLength(0);
            return PcmChannelEncoder.ofRaw(inFormat, file.getChannel(), outFormat);
        } else if ("wav".equals(ext)) {
            RandomAccessFile file = new RandomAccessFile(outFnam, "rw");
            file.setLength(0);
            return PcmChannelEncoder.ofWav(inFormat, file.getChannel(), totalFrames);
        } else {
            throw new IllegalArgumentException("Unrecognized output file format: "+ext);
        }
    }

    public static PcmWriter fileEncoder(PcmFormat inFormat, long totalFrames, String outFnam) throws IOException {
        return fileEncoder(inFormat, totalFrames, outFnam, defaultComprLevel, defaultOQuality, defaultBitrate, defaultMQuality);
    }

    private static int intArg(String v, String option) {
        try {
            return Integer.parseInt(v);
        } catch (Exception ex) {
            System.err.println("Invalid argument to "+option);
            System.exit(2);
            throw new IllegalStateException();
        }
    }

    private static float floatArg(String v, String option) {
        try {
            return Float.parseFloat(v);
        } catch (Exception ex) {
            System.err.println("Invalid argument to "+option);
            System.exit(2);
            throw new IllegalStateException();
        }
    }

    public static void main(String[] args) {
        int comprLevel = defaultComprLevel;
        int bitrate = defaultBitrate;
        int mquality = defaultMQuality;
        float oquality = defaultOQuality;

        String helpText = "Arguments: [options] infile outfile\n\n"
            +"Options:\n"
            +"-level <int>            FLAC compression level, defauls to "+comprLevel+"\n"
            +"-bitrate <int>          MP3 bitrate, defaults to "+bitrate+"\n"
            +"-mquality <int>         MP3 quality, defaults to "+mquality+"\n"
            +"-oquality <float>       Vorbis quality, defaults to "+oquality+"\n"
            +"-help or --help         Print this message\n"
            +"--                 Remaining arguments are file names\n";

        try {
            int argPos = 0;
            while (argPos < args.length) {
                String o = args[argPos];
                if      (o.charAt(0) != '-')   { break; }
                argPos++;
                if      ("--"      .equals(o)) { break; }
                String v = argPos < args.length ? args[argPos++] : "";
                if      ("-level"  .equals(o)) { comprLevel = intArg(v, "-level"); }
                else if ("-bitrate".equals(o)) { bitrate = intArg(v, "-bitrate"); }
                else if ("-mquality".equals(o)) { mquality = intArg(v, "-quality"); }
                else if ("-oquality".equals(o)) { oquality = floatArg(v, "-quality"); }
                else if (o.startsWith("-h") || o.startsWith("--h")) { System.out.println(helpText); return; }
                else {
                    System.err.println("Unregognized option "+o+" (use -h for usage)");
                    System.exit(2);
                }
            }
            if (args.length - argPos != 2) {
                System.err.println("Two file names not provided (use -h for usage)");
                System.exit(2);
            }
            String inFnam = args[argPos];
            String outFnam = args[argPos+1];
            Track tr = Track.single(inFnam);
            RandomAccessFile inFile = new RandomAccessFile(inFnam, "r");
            ReadableByteChannel in = inFile.getChannel();
            ByteBuffer bb = ByteBuffer.allocateDirect(2048*tr.format().fs());
            bb.order(tr.format().order());
            PcmWriter out = fileEncoder(tr.format(),
                                        (inFnam.endsWith(".raw")
                                         ? inFile.length()/tr.format().fs()
                                         : AudioSystem.NOT_SPECIFIED),
                                        outFnam,
                                        comprLevel,
                                        oquality,
                                        bitrate,
                                        mquality);
            tr.decode(0, out);
            out.close();
        } catch (Throwable th) {
            System.err.println(th);
            if (System.getProperty("klipspringer.debug") != null) { th.printStackTrace(); }
            System.exit(1);
        }
    }
}

Version: v4.3.2.2 (2026-05-16T17:03:34+02:00)
Raw file
Source code overview
Klipspringer home