{ $Log: acs_mixer.inc,v $ Revision 1.2 2005/12/30 12:54:42 z0m3ie some error checks Revision 1.1 2005/12/19 18:35:03 z0m3ie *** empty log message *** Revision 1.3 2005/12/04 16:54:34 z0m3ie All classes are renamed, Style TACS... than T... to avoid conflicts with other components (eg TMixer is TACSMixer now) Revision 1.2 2005/09/13 21:54:11 z0m3ie acs is localizeable now (ACS_Strings) Revision 1.1 2005/09/12 22:04:52 z0m3ie modified structure again, fileformats are now in an sperat folder. all File In/Out classes are capsulated from TFileIn and TFileOut Revision 1.4 2005/09/09 21:33:43 z0m3ie linux corrections Revision 1.3 2005/08/31 20:30:40 z0m3ie Mixer Channelname work now minior corrections for Converters Revision 1.2 2005/08/28 20:31:18 z0m3ie linux restructuring for 2.4 Revision 1.1 2005/08/25 20:18:00 z0m3ie Version 2.4 restructure TCDPlayer removed (fits not in component structure) TMP3ToWavConverter removed (fits not in component structure) } type TMixerInfo = record Path : String; Name : String; end; const MAX_MIXERS = 5; (* There shouldn't be more than 5 valid mixers in the system. Right? *) var Mixers : array[0..MAX_MIXERS] of TMixerInfo; // one extra slot for /dev/mixer device function GetChannelMask(Ch : TACSMixerChannel; Request : Integer): LongWord; begin Result := 0; case Request of 0: case Ch of mcVolume: Result := SOUND_MIXER_VOLUME; mcTreble: Result := SOUND_MIXER_TREBLE; mcBass: Result := SOUND_MIXER_BASS; mcSynth: Result := SOUND_MIXER_SYNTH; mcPCM: Result := SOUND_MIXER_PCM; mcSpeaker: Result := SOUND_MIXER_SPEAKER; mcLine: Result := SOUND_MIXER_LINE; mcMic: Result := SOUND_MIXER_MIC; mcCD: Result := SOUND_MIXER_CD; mcIMix: Result := SOUND_MIXER_IMIX; mcAltPCM: Result := SOUND_MIXER_ALTPCM; mcRecLev: Result := SOUND_MIXER_RECLEV; mcUnknown: Result := 0; end; 1: case Ch of mcVolume: Result := SOUND_MIXER_WRITE_VOLUME; mcTreble: Result := SOUND_MIXER_WRITE_TREBLE; mcBass: Result := SOUND_MIXER_WRITE_BASS; mcSynth: Result := SOUND_MIXER_WRITE_SYNTH; mcPCM: Result := SOUND_MIXER_WRITE_PCM; mcSpeaker: Result := SOUND_MIXER_WRITE_SPEAKER; mcLine: Result := SOUND_MIXER_WRITE_LINE; mcMic: Result := SOUND_MIXER_WRITE_MIC; mcCD: Result := SOUND_MIXER_WRITE_CD; mcIMix: Result := SOUND_MIXER_WRITE_IMIX; mcAltPCM: Result := SOUND_MIXER_WRITE_ALTPCM; mcRecLev: Result := SOUND_MIXER_WRITE_RECLEV; mcUnknown: Result := 0; end; 2: case Ch of mcVolume: Result := SOUND_MIXER_READ_VOLUME; mcTreble: Result := SOUND_MIXER_READ_TREBLE; mcBass: Result := SOUND_MIXER_READ_BASS; mcSynth: Result := SOUND_MIXER_READ_SYNTH; mcPCM: Result := SOUND_MIXER_READ_PCM; mcSpeaker: Result := SOUND_MIXER_READ_SPEAKER; mcLine: Result := SOUND_MIXER_READ_LINE; mcMic: Result := SOUND_MIXER_READ_MIC; mcCD: Result := SOUND_MIXER_READ_CD; mcIMix: Result := SOUND_MIXER_READ_IMIX; mcAltPCM: Result := SOUND_MIXER_READ_ALTPCM; mcRecLev: Result := SOUND_MIXER_READ_RECLEV; mcUnknown: Result := 0; end; end; end; function GetChannelType(Mask : Integer) : TACSMixerChannel; begin case Mask of SOUND_MIXER_VOLUME: Result := mcVolume; SOUND_MIXER_TREBLE: Result := mcTreble; SOUND_MIXER_BASS: Result := mcBass; SOUND_MIXER_SYNTH: Result := mcSynth; SOUND_MIXER_PCM: Result := mcPCM; SOUND_MIXER_SPEAKER: Result := mcSpeaker; SOUND_MIXER_LINE: Result := mcLine; SOUND_MIXER_MIC: Result := mcMic; SOUND_MIXER_CD: Result := mcCD; SOUND_MIXER_IMIX: Result := mcIMix; SOUND_MIXER_ALTPCM: Result := mcAltPCM; SOUND_MIXER_RECLEV: Result := mcRecLev; else Result := mcUnknown; end; end; procedure TACSMixer.SetDevNum(Num : Integer); var DevMask, i : Integer; Channel : TACSMixerChannel; begin if Num in [0..MixersCount - 1] then // check [0..0] [0..-1] begin FFileName := Mixers[Num].Path; FMixerName := Mixers[Num].Name; setlength(FChannels,0); _mix_fd := fpopen(PChar(FFileName), O_RDONLY); fpioctl(_mix_fd, SOUND_MIXER_READ_DEVMASK, @DevMask); fpclose(_mix_fd); for i:=0 to 31 do begin if (DevMask and (1 shl i)) <> 0 then begin Channel := GetChannelType(i); if Channel <> mcUnknown then begin setlength(FChannels,length(FChannels)+1); FChannels[length(FChannels)-1] := Channel; end; end; end; end; end; function TACSMixer.GetRecSource; var rs, pow,i : Integer; begin Result := -1; _mix_fd := fpopen(PChar(FFileName), O_RDONLY); fpioctl(_mix_fd, SOUND_MIXER_READ_RECSRC, @rs); fpclose(_mix_fd); pow := 0; while rs <> 1 do begin rs := rs shr 1; Inc(pow); end; for i := 0 to length(FChannels)-1 do if FChannels[i] = GetChannel(pow) then Result := i; end; function TACSMixer.GetVolume; var vol, chan : Integer; begin _mix_fd := fpopen(PChar(FFileName), O_RDONLY); chan := GetChannelMask(FChannels[vChannel], 2); fpioctl(_mix_fd, chan, @vol); fpclose(_mix_fd); if vol > 255 then begin Result.Left := Lo(vol); Result.Right := Lo(vol shr 8); end else Result.Main := vol; end; function TACSMixer.IsStereo; var mask, chan : Integer; begin _mix_fd := fpopen(PChar(FFileName), O_RDONLY); fpioctl(_mix_fd, SOUND_MIXER_READ_STEREODEVS, @mask); chan := GetChannelMask(FChannels[vChannel], 0); fpclose(_mix_fd); Result := (mask and (1 shl chan))<>0; end; function TACSMixer.IsRecordable; var mask, chan : Integer; begin _mix_fd := fpopen(PChar(FFileName), O_RDONLY); fpioctl(_mix_fd, SOUND_MIXER_READ_RECMASK, @mask); chan := GetChannelMask(FChannels[vChannel], 0); fpclose(_mix_fd); Result := (mask and (1 shl chan))<>0; end; procedure TACSMixer.SetRecSource; var chan : Integer; begin chan := 1 shl GetChannelMask(FChannels[vChannel], 0); _mix_fd := fpopen(PChar(FFileName), O_WRONLY); fpioctl(_mix_fd, SOUND_MIXER_WRITE_RECSRC, @chan); fpclose(_mix_fd); if chan <> (1 shl GetChannelMask(FChannels[vChannel], 0)) then raise EACSException.Create(Format(strChannelnotRecordable,[vChannel])); end; function TACSMixer.GetMute(vChannel : integer) : Boolean; begin Result := False; end; procedure TACSMixer.SetMute(vChannel : integer; Mute : Boolean); begin end; procedure TACSMixer.SetVolume; var vol, chan : Integer; begin chan := GetChannelMask(FChannels[vChannel], 1); if IsStereo(vChannel) then vol := vLevel.Left + (vLevel.Right shl 8) else vol := vLevel.Main; _mix_fd := fpopen(PChar(FFileName), O_WRONLY); fpioctl(_mix_fd, chan, @vol); fpclose(_mix_fd); end; destructor TACSMixer.Destroy; begin Setlength(FChannels,0); inherited Destroy; end; function CountMixers : Byte; var fd, i, DevMask : Integer; fname : String; mi : mixer_info; begin Result := 0; for i := 0 to MAX_MIXERS-1 do begin fname := '/dev/mixer'+IntToStr(i-1); try fd := fpopen(PChar(fname), O_RDONLY); except Break; end; if fd = -1 then Break; DevMask := 0; fpioctl(fd, SOUND_MIXER_READ_DEVMASK, @DevMask); if DevMask <> 0 then begin Mixers[Result].Path := fname; fpioctl(fd, SOUND_MIXER_INFO, @mi); Mixers[Result].Name := String(mi.name); Inc(Result); end; fpclose(fd); end; fname := '/dev/mixer'; try fd := fpopen(PChar(fname), O_RDONLY); except Exit; end; if fd = -1 then Exit; fpioctl(fd, SOUND_MIXER_READ_DEVMASK, @DevMask); if DevMask <> 0 then begin Mixers[Result].Path := fname; fpioctl(fd, SOUND_MIXER_INFO, @mi); Mixers[Result].Name := String(mi.name); end; fpclose(fd); Inc(Result); end;