Mercurial > hg > jslab
view src/samer/audio/AudioSource.java @ 8:5e3cbbf173aa tip
Reorganise some more
author | samer |
---|---|
date | Fri, 05 Apr 2019 22:41:58 +0100 |
parents | 5df24c91468d |
children |
line wrap: on
line source
/* * AudioSource.java * * Copyright (c) 2000, Samer Abdallah, King's College London. * All rights reserved. * * This software is provided AS iS and WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ package samer.audio; import samer.tools.*; /** General interface for objects that can supply an audio stream. */ public interface AudioSource { boolean isOpen(); void open() throws Exception; void close(); void dispose(); /** return a task which reads samples into the given buffer * The idea is that the audio source can choose the right * kind of reader depending on the format of the audio stream, * and then handle the conversion to doubles automatically */ Task reader(double buf[], int off, int len); Task reader(float buf[], int off, int len); int getChannels(); float getRate(); public static class Util { /* NB. These copying functions allow NEGATIVE offset (off<0). The semantics * of this is are that n values are copied from source to destination, writing * into the destination starting at the negative offset, but that values before * index 0 will never be accessed, hence, they are not actually copied. Only * the last n-off values will be available in dst starting from index 0. * This is useful as it allows block-wise audio input where the block lenght * is smaller than the step length. */ public static void shortToDoubleMixDown(byte [] src, double [] dst, int off, int n, int m) { double a = (1.0/(m*32768.0)); // scaling factor including division by mixdown factor m int skip = off<0 ? -off : 0; for (int i=2*m*skip, j=off+skip; j<n+off; j++) { dst[j] = 0; for (int k=0; k<m; k++) dst[j] += a*((src[i++]&0xff) | src[i++]<<8); } } public static void mediumToDouble(byte [] src, double [] dst, int off, int n) { int i, j; if (off<0) { i= 3*(-off); j=0; } else { i=0; j=off; } while (j<n+off) dst[j++] = (1.0/8388608.0)*((src[i++]&0xff) | src[i++]<<8 | src[i++]<<16); } public static void shortToDouble(byte [] src, double [] dst, int off, int n) { int i, j; if (off<0) { i= 2*(-off); j=0; } else { i=0; j=off; } while (j<n+off) dst[j++] = (1.0/32768.0)*((src[i++]&0xff) | src[i++]<<8); } public static void byteToDouble(byte [] src, double [] dst, int off, int n) { int i, j; if (off<0) { i= -off; j=0; } else { i=0; j=off; } while (j<n+off) dst[j++] = (1.0/256.0)*(src[i++]&0xff)-128.0; } public static void shortToFloatMixDown(byte [] src, float [] dst, int off, int n, int m) { int skip = off<0 ? -off : 0; float a = (1F/(m*32768F)); // scaling factor including division by mixdown factor m for (int i=2*m*skip, j=off+skip; j<n+off; j++) { dst[j] = 0; for (int k=0; k<m; k++) dst[j] += a*((src[i++]&0xff) | src[i++]<<8); } } public static void shortToFloat(byte [] src, float [] dst, int off, int n) { int i, j; if (off<0) { i= -2*off; j=0; } else { i=0; j=off; } while (j<n+off) dst[j++] = (1F/32768F)*((src[i++]&0xff) | src[i++]<<8); } public static void byteToFloat(byte [] src, float [] dst, int off, int n) { int i, j; if (off<0) { i= -off; j=0; } else { i=0; j=off; } while (j<n+off) dst[j++] = (1F/256F)*(src[i++]&0xff)-128F; } } }