Package vavi.sound.mobile

Source Code of vavi.sound.mobile.BasicAudioEngine

/*
* Copyright (c) 2003 by Naohide Sano, All rights reserved.
*
* Programmed by Naohide Sano
*/

package vavi.sound.mobile;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteOrder;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

import vavi.util.Debug;


/**
* Abstract AudioEngine.
*
* @author <a href="mailto:vavivavi@yahoo.co.jp">Naohide Sano</a> (nsano)
* @version 0.00 020903 nsano initial version <br>
*/
public abstract class BasicAudioEngine implements AudioEngine {

    /** */
    protected Data[] datum;

    /* */
    public void setData(int streamNumber,
                        int channel,
                        int sampleRate,
                        int bits,
                        int channels,
                        byte[] adpcm, boolean continued) {
        Data data;
        if (datum[streamNumber] == null) {
            data = new Data();
            data.channel = channel;
            data.sampleRate = sampleRate;
            data.bits = bits;
            data.channels = channels;
        } else {
            data = datum[streamNumber];
        }
        if (data.continued) {
            byte[] temp = new byte[data.adpcm.length + adpcm.length];
            System.arraycopy(data.adpcm, 0, temp, 0, data.adpcm.length);
            System.arraycopy(adpcm, 0, temp, data.adpcm.length, adpcm.length);
            data.adpcm = temp;
        } else {
            data.adpcm = adpcm;
        }
        data.continued = continued;
        datum[streamNumber] = data;

try {
OutputStream os = null;
if (fileName != null) {
Debug.println("���������������� adpcm out to file: " + fileName);
  os = new BufferedOutputStream(new FileOutputStream(fileName, true));
  os.write(adpcm, 0, adpcm.length);
  os.flush();
  os.close();
}
} catch (IOException e) {
Debug.printStackTrace(e);
}
    }

    /** */
    public void stop(int streamNumber) {
    }

    /** */
    protected abstract int getChannels(int streamNumber);

    /** */
    protected abstract InputStream[] getInputStreams(int streamNumber, int channels);

    /** */
    public void start(int streamNumber) {

        int channels = getChannels(streamNumber);
        if (channels == -1) {
Debug.println("always used: no: " + streamNumber + ", ch: " + datum[streamNumber].channel);
            return;
        }

        AudioFormat audioFormat = new AudioFormat(
            AudioFormat.Encoding.PCM_SIGNED,
            datum[streamNumber].sampleRate,
            16,
            channels,
            2 * channels,
            datum[streamNumber].sampleRate,
            false);
Debug.println(audioFormat);

        try {

//Debug.println(data.length);
            InputStream[] iss = getInputStreams(streamNumber, channels);

//Debug.println("is: " + is.available());
OutputStream os = null;
if (pcmFileName != null) {
Debug.println("���������������� output PCM to file: " + pcmFileName);
os = new BufferedOutputStream(new FileOutputStream(pcmFileName));
}

            DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
            SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
            line.open(audioFormat);
            line.start();
FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
double gain = .2d; // number between 0 and 1 (loudest)
float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
gainControl.setValue(dB);
            byte[] buf = new byte[1024];
            while (iss[0].available() > 0) {
                if (channels == 1) {
                    int l = iss[0].read(buf, 0, 1024);
//Debug.dump(buf, 64);
                    line.write(buf, 0, l);
if (os != null) {
os.write(buf, 0, l);
}
                } else {
                    int lL = iss[0].read(buf, 0, 512);
                    /*int lR = */iss[1].read(buf, 512, 512);
//System.err.println("l : " + lL + ", r: " + lR);
                    for (int i = 0; i < lL / 2; i++) {
                        byte[] temp = new byte[4];
                        temp[0] = buf[i * 2];
                        temp[1] = buf[i * 2 + 1];
                        temp[2] = buf[512 + i * 2];
                        temp[3] = buf[512 + i * 2 + 1];
                        line.write(temp, 0, 4);
                    }
                }
            }
            line.drain();
            line.stop();
            line.close();
if (os != null) {
os.flush();
os.close();
}
        } catch (IOException e) {
            throw (RuntimeException) new IllegalStateException().initCause(e);
        } catch (LineUnavailableException e) {
            throw (RuntimeException) new IllegalStateException().initCause(e);
        }
    }

    //-------------------------------------------------------------------------

    /** */
    protected abstract OutputStream getOutputStream(OutputStream os);

    /* */
    public byte[] encode(int bits, int channels, byte[] pcm) {
        try {
            if (channels == 1) {
                // monaural
                InputStream is = new ByteArrayInputStream(pcm);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                OutputStream os = getOutputStream(baos);
Debug.println("pcm length: " + is.available());
                while (is.available() > 0) {
                    int c = is.read();
                    if (c == -1) {
Debug.println("read returns -1");
                        break;
                    }
                    os.write(c);
                }
   
                return baos.toByteArray();
            } else {
                // stereo
                byte[][] monos = Util.toMono(pcm, 16, ByteOrder.LITTLE_ENDIAN);
                // L
                InputStream is = new ByteArrayInputStream(monos[0]);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                OutputStream os = getOutputStream(baos);
Debug.println("pcm L length: " + is.available());
                while (is.available() > 0) {
                    int c = is.read();
                    if (c == -1) {
Debug.println("Illegal EOF L: " + is.available());
                        break;
                    }
                    os.write(c);
                }
                byte[] monoL = baos.toByteArray();
                // R
                is = new ByteArrayInputStream(monos[1]);
                baos = new ByteArrayOutputStream();
                os = getOutputStream(baos);
Debug.println("pcm R length: " + is.available());
                while (is.available() > 0) {
                    int c = is.read();
                    if (c == -1) {
Debug.println("Illegal EOF R: " + is.available());
                        break;
                    }
                    os.write(c);
                }
                byte[] monoR = baos.toByteArray();
                return Util.concatenate(monoL, monoR);
            }
        } catch (IOException e) {
            throw (RuntimeException) new IllegalStateException().initCause(e);
        }
    }

    //-------------------------------------------------------------------------

    /** */
    private static String fileName;

    /** */
    private static String pcmFileName;

    /**
     * Tests this class.
     *
     * usage: java $0 mfi_file adpcm
     */
    public static void main(String[] args) throws Exception {

        if (args.length >= 2) {
            fileName = args[1];
        }
        if (args.length >= 3) {
            pcmFileName = args[2];
        }

        vavi.sound.mfi.Sequencer sequencer = vavi.sound.mfi.MfiSystem.getSequencer();
        sequencer.open();
        vavi.sound.mfi.Sequence sequence = vavi.sound.mfi.MfiSystem.getSequence(new File(args[0]));
        sequencer.setSequence(sequence);
        sequencer.addMetaEventListener(new vavi.sound.mfi.MetaEventListener() {
            public void meta(vavi.sound.mfi.MetaMessage meta) {
Debug.println(meta.getType());
                if (meta.getType() == 47) {
                    System.exit(0);
                }
            }
        });
        sequencer.start();
    }
}

/* */ 
TOP

Related Classes of vavi.sound.mobile.BasicAudioEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.