diff --git a/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java b/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java index f0cfe14e..c5d6a81b 100644 --- a/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java +++ b/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java @@ -89,6 +89,7 @@ import io.github.dsheirer.module.decode.tait.Tait1200DecoderState; import io.github.dsheirer.module.demodulate.am.AMDemodulatorModule; import io.github.dsheirer.module.demodulate.audio.DemodulatedAudioFilterModule; import io.github.dsheirer.module.demodulate.fm.FMDemodulatorModule; +import io.github.dsheirer.source.SourceType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -147,31 +148,44 @@ public class DecoderFactory switch(decodeConfig.getDecoderType()) { case AM: + if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER) + { + modules.add(new AMDemodulatorModule()); + //TODO: update AM demodulator to produce demodulated 8 kHz audio and delete the following filter module + modules.add(new DemodulatedAudioFilterModule(4000, 6000)); + } + modules.add(new AMDecoder(decodeConfig)); modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.AM, channel.getName())); - modules.add(new AMDemodulatorModule()); -//TODO: update AM demodulator to produce demodulated 8 kHz audio and delete the following filter module - modules.add(new DemodulatedAudioFilterModule(4000, 6000)); modules.add(new AudioModule(metadata)); break; case NBFM: modules.add(new NBFMDecoder(decodeConfig)); modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.NBFM, channel.getName())); - modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); modules.add(new AudioModule(metadata)); + if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER) + { + modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); + } break; case LTR_STANDARD: MessageDirection direction = ((DecodeConfigLTRStandard) decodeConfig).getMessageDirection(); modules.add(new LTRStandardDecoder(aliasList, direction)); modules.add(new LTRStandardDecoderState(aliasList)); - modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); modules.add(new AudioModule(metadata)); + if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER) + { + modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); + } break; case LTR_NET: modules.add(new LTRNetDecoder((DecodeConfigLTRNet) decodeConfig, aliasList)); modules.add(new LTRNetDecoderState(aliasList)); - modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); modules.add(new AudioModule(metadata)); + if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER) + { + modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); + } break; case MPT1327: DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327) decodeConfig; @@ -179,8 +193,11 @@ public class DecoderFactory Sync sync = mptConfig.getSync(); modules.add(new MPT1327Decoder(aliasList, sync)); modules.add(new MPT1327DecoderState(aliasList, channelMap, channelType, mptConfig.getCallTimeout() * 1000)); - modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); modules.add(new AudioModule(metadata)); + if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER) + { + modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); + } if(channelType == ChannelType.STANDARD) { @@ -192,15 +209,17 @@ public class DecoderFactory case PASSPORT: modules.add(new PassportDecoder(decodeConfig, aliasList)); modules.add(new PassportDecoderState(aliasList)); - modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); modules.add(new AudioModule(metadata)); + if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER) + { + modules.add(new FMDemodulatorModule(CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE)); + } break; case P25_PHASE1: DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1) decodeConfig; Modulation modulation = p25Config.getModulation(); - switch(modulation) { case C4FM: @@ -288,8 +307,7 @@ public class DecoderFactory { if(module instanceof Decoder) { - filterSet.addFilters(getMessageFilter( - ((Decoder) module).getDecoderType())); + filterSet.addFilters(getMessageFilter(((Decoder)module).getDecoderType())); } } diff --git a/src/main/java/io/github/dsheirer/source/mixer/MixerManager.java b/src/main/java/io/github/dsheirer/source/mixer/MixerManager.java index 7fa74a20..fad3a366 100644 --- a/src/main/java/io/github/dsheirer/source/mixer/MixerManager.java +++ b/src/main/java/io/github/dsheirer/source/mixer/MixerManager.java @@ -1,19 +1,17 @@ /******************************************************************************* - * SDR Trunk - * Copyright (C) 2014 Dennis Sheirer - * - * This program 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. - * - * This program 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 this program. If not, see + * sdr-trunk + * Copyright (C) 2014-2018 Dennis Sheirer + * + * This program 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. + * + * This program 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 this program. + * If not, see + * ******************************************************************************/ package io.github.dsheirer.source.mixer; @@ -42,395 +40,369 @@ import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.List; +import java.util.Map; public class MixerManager { - private final static Logger mLog = - LoggerFactory.getLogger( MixerManager.class ); + private final static Logger mLog = LoggerFactory.getLogger(MixerManager.class); - private List mInputMixers = new ArrayList<>(); - private List mOutputMixers = new ArrayList<>(); - private HashMap mMixerTuners = new HashMap<>(); + private List mInputMixers = new ArrayList<>(); + private List mOutputMixers = new ArrayList<>(); + private Map mMixerTuners = new HashMap<>(); - public MixerManager() - { - loadMixers(); - } - - public RealMixerSource getSource( SourceConfiguration config ) + public MixerManager() { - RealMixerSource retVal = null; - - if( config instanceof SourceConfigMixer) - { - SourceConfigMixer mixerConfig = (SourceConfigMixer)config; + loadMixers(); + } - String mixerName = mixerConfig.getMixer(); + public RealMixerSource getSource(SourceConfiguration config) + { + RealMixerSource retVal = null; - if( mixerName != null ) - { - InputMixerConfiguration mixer = getInputMixer( mixerName ); + if(config instanceof SourceConfigMixer) + { + SourceConfigMixer mixerConfig = (SourceConfigMixer)config; - if( mixer != null ) - { - MixerChannel channel = mixerConfig.getChannel(); - - if( mixer.supportsChannel( channel ) ) - { - - if( channel == MixerChannel.MONO ) - { - DataLine.Info info = - new DataLine.Info(TargetDataLine.class, - AudioFormats.PCM_SIGNED_48KHZ_16BITS_MONO ); + String mixerName = mixerConfig.getMixer(); + + if(mixerName != null) + { + InputMixerConfiguration mixer = getInputMixer(mixerName); + + if(mixer != null) + { + MixerChannel channel = mixerConfig.getChannel(); + + if(mixer.supportsChannel(channel)) + { + + if(channel == MixerChannel.MONO) + { + DataLine.Info info = new DataLine.Info(TargetDataLine.class, + AudioFormats.PCM_SIGNED_8KHZ_16BITS_MONO); + + TargetDataLine dataLine; - TargetDataLine dataLine; - try { - dataLine = (TargetDataLine)mixer - .getMixer().getLine( info ); + dataLine = (TargetDataLine)mixer.getMixer().getLine(info); - if( dataLine != null ) - { - return new RealMixerSource( dataLine, - AudioFormats.PCM_SIGNED_48KHZ_16BITS_MONO, - new ShortAdapter() ); - } + if(dataLine != null) + { + return new RealMixerSource(dataLine, AudioFormats.PCM_SIGNED_8KHZ_16BITS_MONO, + new ShortAdapter()); + } } - catch ( LineUnavailableException e ) + catch(LineUnavailableException e) { - mLog.error( "couldn't get mixer data line " + - "for [" + mixerName + "] for channel [" + - channel.name() + "]", e ); + mLog.error("couldn't get mixer data line for [" + mixerName + "] for channel [" + + channel.name() + "]", e); } - - } - else - { - DataLine.Info info = - new DataLine.Info(TargetDataLine.class, - AudioFormats.PCM_SIGNED_48KHZ_16BITS_STEREO ); - TargetDataLine dataLine; + } + else + { + DataLine.Info info = new DataLine.Info(TargetDataLine.class, + AudioFormats.PCM_SIGNED_8KHZ_16BITS_STEREO); - try + TargetDataLine dataLine; + + try { - dataLine = (TargetDataLine)mixer - .getMixer().getLine( info ); + dataLine = (TargetDataLine)mixer.getMixer().getLine(info); - if( dataLine != null ) - { - return new RealMixerSource( dataLine, - AudioFormats.PCM_SIGNED_48KHZ_16BITS_STEREO, - new ChannelShortAdapter( - mixerConfig.getChannel() ) ); - } + if(dataLine != null) + { + return new RealMixerSource(dataLine, AudioFormats.PCM_SIGNED_8KHZ_16BITS_STEREO, + new ChannelShortAdapter(mixerConfig.getChannel())); + } } - catch ( LineUnavailableException e ) + catch(LineUnavailableException e) { - mLog.error( "couldn't get mixer data line " + - "for [" + mixerName + "] for channel [" + - channel.name() + "]", e ); + mLog.error("couldn't get mixer data line for [" + mixerName + "] for channel [" + + channel.name() + "]", e); } - } - } - } - } - } + } + } + } + } + } - return null; + return null; } - + public InputMixerConfiguration[] getInputMixers() { - return mInputMixers.toArray( new InputMixerConfiguration[ mInputMixers.size() ] ); + return mInputMixers.toArray(new InputMixerConfiguration[mInputMixers.size()]); } - - public InputMixerConfiguration getInputMixer( String name ) + + public InputMixerConfiguration getInputMixer(String name) { - for( InputMixerConfiguration mixer: mInputMixers ) - { - if( mixer.getMixerName().contentEquals( name ) ) - { - return mixer; - } - } - - return null; + for(InputMixerConfiguration mixer : mInputMixers) + { + if(mixer.getMixerName().contentEquals(name)) + { + return mixer; + } + } + + return null; } public MixerChannelConfiguration[] getOutputMixers() { - return mOutputMixers.toArray( new MixerChannelConfiguration[ mOutputMixers.size() ] ); + return mOutputMixers.toArray(new MixerChannelConfiguration[mOutputMixers.size()]); } - + public Collection getMixerTunerDataLines() { - if( mMixerTuners.isEmpty() ) - { - return Collections.emptyList(); - } - else - { - return mMixerTuners.values(); - } - } - - private void loadMixers() - { - StringBuilder sb = new StringBuilder(); - - sb.append( "loading system mixer devices\n" ); - - for( Mixer.Info mixerInfo: AudioSystem.getMixerInfo() ) + if(mMixerTuners.isEmpty()) { - //Sort between the mixers and the tuner mixers, and load each - MixerTunerType mixerTunerType = MixerTunerType.getMixerTunerType( mixerInfo ); - - if( mixerTunerType == MixerTunerType.UNKNOWN ) - { - Mixer mixer = AudioSystem.getMixer( mixerInfo ); + return Collections.emptyList(); + } + else + { + return mMixerTuners.values(); + } + } - if( mixer != null ) + private void loadMixers() + { + StringBuilder sb = new StringBuilder(); + + sb.append("loading system mixer devices\n"); + + for(Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) + { + //Sort between the mixers and the tuner mixers, and load each + MixerTunerType mixerTunerType = MixerTunerType.getMixerTunerType(mixerInfo); + + if(mixerTunerType == MixerTunerType.UNKNOWN) + { + Mixer mixer = AudioSystem.getMixer(mixerInfo); + + if(mixer != null) { - EnumSet inputChannels = getSupportedTargetChannels( mixer ); - - if( inputChannels != null ) - { - mInputMixers.add( - new InputMixerConfiguration( mixer, inputChannels ) ); - - sb.append( "\t[LOADED] Input: " + mixerInfo.getName() + - " CHANNELS: " + inputChannels + "\n" ); - } - - EnumSet outputChannels = getSupportedSourceChannels( mixer ); - - if( outputChannels != null ) - { - for( MixerChannel channel: outputChannels ) - { - mOutputMixers.add( new MixerChannelConfiguration( mixer, channel ) ); - } + EnumSet inputChannels = getSupportedTargetChannels(mixer); - sb.append( "\t[LOADED] Output: " + mixerInfo.getName() + - " CHANNELS: " + outputChannels + "\n" ); - } + if(inputChannels != null) + { + mInputMixers.add(new InputMixerConfiguration(mixer, inputChannels)); + + sb.append("\t[LOADED] Input: " + mixerInfo.getName() + " CHANNELS: " + inputChannels + "\n"); + } + + EnumSet outputChannels = getSupportedSourceChannels(mixer); + + if(outputChannels != null) + { + for(MixerChannel channel : outputChannels) + { + mOutputMixers.add(new MixerChannelConfiguration(mixer, channel)); + } + + sb.append("\t[LOADED] Output: " + mixerInfo.getName() + " CHANNELS: " + outputChannels + "\n"); + } } else { - sb.append( "\t[NOT LOADED] Mixer:" + mixerInfo.getName() + - " - couldn't get mixer\n" ); + sb.append("\t[NOT LOADED] Mixer:" + mixerInfo.getName() + " - couldn't get mixer\n"); } - } - else //Process as a Mixer-based tuner data line - { - TargetDataLine tdl = - getTargetDataLine( mixerInfo, - mixerTunerType.getAudioFormat() ); + } + else + { + TargetDataLine tdl = getTargetDataLine(mixerInfo, mixerTunerType.getAudioFormat()); - if( tdl != null ) - { - switch( mixerTunerType ) - { - case FUNCUBE_DONGLE_PRO: - case FUNCUBE_DONGLE_PRO_PLUS: - mMixerTuners.put( mixerInfo.getName(), - new MixerTunerDataLine( tdl, mixerTunerType ) ); - sb.append( "\t[LOADED] FunCube Dongle Mixer Tuner:" + mixerInfo.getName() + "[" + mixerTunerType.getDisplayString() + "]\n" ); - break; - case UNKNOWN: - default: - sb.append( "\t[NOT LOADED] Tuner:" + mixerInfo.getName() + " - unrecognized tuner type\n" ); - break; - } - } - } + if(tdl != null) + { + switch(mixerTunerType) + { + case FUNCUBE_DONGLE_PRO: + case FUNCUBE_DONGLE_PRO_PLUS: + mMixerTuners.put(mixerInfo.getName(), + new MixerTunerDataLine(tdl, mixerTunerType)); + sb.append("\t[LOADED] FunCube Dongle Mixer Tuner:" + mixerInfo.getName() + "[" + mixerTunerType.getDisplayString() + "]\n"); + break; + case UNKNOWN: + default: + sb.append("\t[NOT LOADED] Tuner:" + mixerInfo.getName() + " - unrecognized tuner type\n"); + break; + } + } + } } - - mLog.info( sb.toString() ); - } - - public HashMap getMixerTuners() - { - return mMixerTuners; - } - - private TargetDataLine getTargetDataLine( Mixer.Info mixerInfo, AudioFormat format ) - { - TargetDataLine retVal = null; - - Mixer mixer = AudioSystem.getMixer( mixerInfo ); - if( mixer != null ) + mLog.info(sb.toString()); + } + + public Map getMixerTuners() + { + return mMixerTuners; + } + + private TargetDataLine getTargetDataLine(Mixer.Info mixerInfo, AudioFormat format) + { + TargetDataLine retVal = null; + + Mixer mixer = AudioSystem.getMixer(mixerInfo); + + if(mixer != null) { try { - DataLine.Info datalineInfo= - new DataLine.Info(TargetDataLine.class, format ); + DataLine.Info datalineInfo = new DataLine.Info(TargetDataLine.class, format); - retVal = (TargetDataLine) mixer.getLine( datalineInfo ); + retVal = (TargetDataLine)mixer.getLine(datalineInfo); } - catch( Exception e ) + catch(Exception e) { - //Do nothing ... we couldn't get the TDL + //Do nothing ... we couldn't get the TDL } } - + return retVal; - } - - private EnumSet getSupportedTargetChannels( Mixer mixer ) - { - DataLine.Info stereoInfo= - new DataLine.Info(TargetDataLine.class, - AudioFormats.PCM_SIGNED_48KHZ_16BITS_STEREO ); + } - boolean stereoSupported = mixer.isLineSupported( stereoInfo ); - - DataLine.Info monoInfo= - new DataLine.Info(TargetDataLine.class, - AudioFormats.PCM_SIGNED_48KHZ_16BITS_MONO ); + private EnumSet getSupportedTargetChannels(Mixer mixer) + { + DataLine.Info stereoInfo = new DataLine.Info(TargetDataLine.class, + AudioFormats.PCM_SIGNED_8KHZ_16BITS_STEREO); - boolean monoSupported = mixer.isLineSupported( monoInfo ); - - if( stereoSupported && monoSupported ) + boolean stereoSupported = mixer.isLineSupported(stereoInfo); + + DataLine.Info monoInfo = new DataLine.Info(TargetDataLine.class, + AudioFormats.PCM_SIGNED_8KHZ_16BITS_MONO); + + boolean monoSupported = mixer.isLineSupported(monoInfo); + + if(stereoSupported && monoSupported) { - return EnumSet.of( MixerChannel.LEFT, - MixerChannel.RIGHT, - MixerChannel.MONO ); + return EnumSet.of(MixerChannel.LEFT, MixerChannel.RIGHT, MixerChannel.MONO); } - else if( stereoSupported ) + else if(stereoSupported) { - return EnumSet.of( MixerChannel.LEFT, - MixerChannel.RIGHT, - MixerChannel.MONO ); + return EnumSet.of(MixerChannel.LEFT, MixerChannel.RIGHT, MixerChannel.MONO); } - else if( monoSupported ) + else if(monoSupported) { - return EnumSet.of( MixerChannel.MONO ); + return EnumSet.of(MixerChannel.MONO); } - + return null; - } + } - /** - * Returns enumset of SourceDataLine (audio output) channels - * (MONO and/or STEREO) supported by the mixer, or null if the mixer doesn't - * have any source data lines. - */ - private EnumSet getSupportedSourceChannels( Mixer mixer ) - { - DataLine.Info stereoInfo= - new DataLine.Info(SourceDataLine.class, - AudioFormats.PCM_SIGNED_48KHZ_16BITS_STEREO ); + /** + * Returns enumset of SourceDataLine (audio output) channels + * (MONO and/or STEREO) supported by the mixer, or null if the mixer doesn't + * have any source data lines. + */ + private EnumSet getSupportedSourceChannels(Mixer mixer) + { + DataLine.Info stereoInfo = new DataLine.Info(SourceDataLine.class, + AudioFormats.PCM_SIGNED_8KHZ_16BITS_STEREO); - boolean stereoSupported = mixer.isLineSupported( stereoInfo ); - - DataLine.Info monoInfo= - new DataLine.Info(SourceDataLine.class, - AudioFormats.PCM_SIGNED_48KHZ_16BITS_MONO ); + boolean stereoSupported = mixer.isLineSupported(stereoInfo); - boolean monoSupported = mixer.isLineSupported( monoInfo ); - - if( stereoSupported && monoSupported ) + DataLine.Info monoInfo = new DataLine.Info(SourceDataLine.class, AudioFormats.PCM_SIGNED_8KHZ_16BITS_MONO); + + boolean monoSupported = mixer.isLineSupported(monoInfo); + + if(stereoSupported && monoSupported) { - return EnumSet.of( MixerChannel.MONO, - MixerChannel.STEREO ); + return EnumSet.of(MixerChannel.MONO, MixerChannel.STEREO); } - else if( stereoSupported ) + else if(stereoSupported) { - return EnumSet.of( MixerChannel.STEREO ); + return EnumSet.of(MixerChannel.STEREO); } - else if( monoSupported ) + else if(monoSupported) { - return EnumSet.of( MixerChannel.MONO ); + return EnumSet.of(MixerChannel.MONO); } - + return null; - } - - public static String getMixerDevices() - { - StringBuilder sb = new StringBuilder(); - - for( Mixer.Info mixerInfo: AudioSystem.getMixerInfo() ) - { - sb.append( "\n--------------------------------------------------" ); - sb.append( "\nMIXER name:" + mixerInfo.getName() + - "\n desc:" + mixerInfo.getDescription() + - "\n vendor:" + mixerInfo.getVendor() + - "\n version:" + mixerInfo.getVersion() + - "\n" ); - - Mixer mixer = AudioSystem.getMixer( mixerInfo ); + } - Line.Info[] sourceLines = mixer.getSourceLineInfo(); - - for( Line.Info lineInfo: sourceLines ) - { - sb.append( " SOURCE LINE desc:" + lineInfo.toString() + - "\n class:" + lineInfo.getClass() + - "\n lineclass:" + lineInfo.getLineClass() + - "\n" ); - } + public static String getMixerDevices() + { + StringBuilder sb = new StringBuilder(); - Line.Info[] targetLines = mixer.getTargetLineInfo(); - - for( Line.Info lineInfo: targetLines ) - { - sb.append( " TARGET LINE desc:" + lineInfo.toString() + - "\n class:" + lineInfo.getClass() + - "\n lineclass:" + lineInfo.getLineClass() + - "\n" ); - } - - Line.Info portInfo = new Line.Info( Port.class ); - - if( mixer.isLineSupported( portInfo ) ) - { - sb.append( "**PORT LINE IS SUPPORTED BY THIS MIXER***\n" ); - } - } - - return sb.toString(); - } - - public class InputMixerConfiguration - { - private Mixer mMixer; - private EnumSet mChannels; - - public InputMixerConfiguration( Mixer mixer, EnumSet channels ) - { - mMixer = mixer; - mChannels = channels; - } - - public Mixer getMixer() - { - return mMixer; - } - - public String getMixerName() - { - return mMixer.getMixerInfo().getName(); - } - - public EnumSet getChannels() - { - return mChannels; - } - - public boolean supportsChannel( MixerChannel channel ) - { - return mChannels.contains( channel ); - } - - public String toString() - { - return mMixer.getMixerInfo().getName(); - } - } + for(Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) + { + sb.append("\n--------------------------------------------------"); + sb.append("\nMIXER name:" + mixerInfo.getName() + + "\n desc:" + mixerInfo.getDescription() + + "\n vendor:" + mixerInfo.getVendor() + + "\n version:" + mixerInfo.getVersion() + + "\n"); + + Mixer mixer = AudioSystem.getMixer(mixerInfo); + + Line.Info[] sourceLines = mixer.getSourceLineInfo(); + + for(Line.Info lineInfo : sourceLines) + { + sb.append(" SOURCE LINE desc:" + lineInfo.toString() + + "\n class:" + lineInfo.getClass() + + "\n lineclass:" + lineInfo.getLineClass() + + "\n"); + } + + Line.Info[] targetLines = mixer.getTargetLineInfo(); + + for(Line.Info lineInfo : targetLines) + { + sb.append(" TARGET LINE desc:" + lineInfo.toString() + + "\n class:" + lineInfo.getClass() + + "\n lineclass:" + lineInfo.getLineClass() + + "\n"); + } + + Line.Info portInfo = new Line.Info(Port.class); + + if(mixer.isLineSupported(portInfo)) + { + sb.append("**PORT LINE IS SUPPORTED BY THIS MIXER***\n"); + } + } + + return sb.toString(); + } + + public class InputMixerConfiguration + { + private Mixer mMixer; + private EnumSet mChannels; + + public InputMixerConfiguration(Mixer mixer, EnumSet channels) + { + mMixer = mixer; + mChannels = channels; + } + + public Mixer getMixer() + { + return mMixer; + } + + public String getMixerName() + { + return mMixer.getMixerInfo().getName(); + } + + public EnumSet getChannels() + { + return mChannels; + } + + public boolean supportsChannel(MixerChannel channel) + { + return mChannels.contains(channel); + } + + public String toString() + { + return mMixer.getMixerInfo().getName(); + } + } } diff --git a/src/main/java/io/github/dsheirer/source/mixer/RealMixerSource.java b/src/main/java/io/github/dsheirer/source/mixer/RealMixerSource.java index ba4391d7..70b996c9 100644 --- a/src/main/java/io/github/dsheirer/source/mixer/RealMixerSource.java +++ b/src/main/java/io/github/dsheirer/source/mixer/RealMixerSource.java @@ -1,19 +1,17 @@ /******************************************************************************* - * SDR Trunk - * Copyright (C) 2014 Dennis Sheirer + * sdr-trunk + * Copyright (C) 2014-2018 Dennis Sheirer * - * This program 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. + * This program 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. * - * This program 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. + * This program 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 this program. + * If not, see * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see ******************************************************************************/ package io.github.dsheirer.source.mixer; @@ -63,9 +61,7 @@ public class RealMixerSource extends RealSource * mixer into float array data. Can optionally invert the channel data if * the left/right stereo channels are inverted. */ - public RealMixerSource(TargetDataLine targetDataLine, - AudioFormat format, - ISampleAdapter sampleAdapter) + public RealMixerSource(TargetDataLine targetDataLine, AudioFormat format, ISampleAdapter sampleAdapter) { mTargetDataLine = targetDataLine; mAudioFormat = format;