Skip to content

Commit

Permalink
Improved default session handling and freeze fix
Browse files Browse the repository at this point in the history
  • Loading branch information
XScorpion2 committed Nov 2, 2020
1 parent 14a84fa commit c053ea5
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 45 deletions.
10 changes: 5 additions & 5 deletions Desktop/Application/MaxMix/Framework/AppExtensions.cs
Expand Up @@ -21,14 +21,14 @@ public static DeviceSettings ToDeviceSettings(this SettingsViewModel model)
return settings;
}

public static SessionData ToSessionData(this ISession audioDevice, int index)
public static SessionData ToSessionData(this ISession[] audioDevices, int index)
{
SessionData session = SessionData.Default();
session.name = audioDevice.DisplayName;
session.name = audioDevices[index].DisplayName;
session.data.id = (byte)index;
session.data.isDefault = audioDevice.IsDefault;
session.data.volume = (byte)audioDevice.Volume;
session.data.isMuted = audioDevice.IsMuted;
session.data.isDefault = audioDevices[index].IsDefault;
session.data.volume = (byte)audioDevices[index].Volume;
session.data.isMuted = audioDevices[index].IsMuted;
return session;
}
}
Expand Down
2 changes: 0 additions & 2 deletions Desktop/Application/MaxMix/Services/Audio/AudioDevice.cs
Expand Up @@ -208,8 +208,6 @@ public void Dispose()
// Do disposal chains, each can throw
try { _deviceEnumerator.Dispose(); }
catch { }
try { _endpointVolume.Dispose(); }
catch { }
try { Device.Dispose(); }
catch { }

Expand Down
2 changes: 1 addition & 1 deletion Desktop/Application/MaxMix/Services/Audio/AudioSession.cs
Expand Up @@ -64,7 +64,7 @@ public AudioSession(AudioSessionControl session)
/// <inheritdoc/>
public string DisplayName { get; protected set; }

public bool IsDefault => false;
public bool IsDefault => IsSystemSound;

/// <inheritdoc/>
public bool IsSystemSound { get; protected set; }
Expand Down
Expand Up @@ -11,11 +11,12 @@ namespace MaxMix.Services.Audio
public class AudioSessionGroup : IAudioSession
{
#region Constructor
public AudioSessionGroup(int id, string displayName)
public AudioSessionGroup(int id, string displayName, bool isDefault)
{
Id = id;
DisplayName = displayName;
SessionIdentifier = $"{Id}: {DisplayName}";
IsDefault = isDefault;
}
#endregion

Expand Down Expand Up @@ -44,7 +45,7 @@ public AudioSessionGroup(int id, string displayName)
public string DisplayName { get; protected set; }

/// <inheritdoc/>
public bool IsDefault => false;
public bool IsDefault { get; protected set; }

/// <inheritdoc/>
public int Volume
Expand Down
Expand Up @@ -128,6 +128,13 @@ public ISession[] GetSessions(DisplayMode mode)
return _devices.Values.Where(x => x.Flow == DeviceFlow.Output).OrderBy(x => x.Id).ToArray();
return null;
}

public void GetSessionCounts(out int output, out int input, out int application)
{
output = _devices.Values.Count(x => x.Flow == DeviceFlow.Output);
input = _devices.Values.Count(x => x.Flow == DeviceFlow.Input);
application = _sessionGoups.Values.Count;
}
#endregion

#region Private Methods
Expand Down Expand Up @@ -177,7 +184,7 @@ private void RegisterSession(IAudioSession session)
}
else
{
var sessionGroup = new AudioSessionGroup(session.Id, session.DisplayName);
var sessionGroup = new AudioSessionGroup(session.Id, session.DisplayName, session.IsDefault);
sessionGroup.AddSession(session);

_sessionGoups.Add(sessionGroup.Id, sessionGroup);
Expand Down
Expand Up @@ -9,6 +9,7 @@ internal interface IAudioSessionService
void SetItemVolume(int id, int volume, bool isMuted);
void SetDefaultEndpoint(int id);
ISession[] GetSessions(DisplayMode mode);
void GetSessionCounts(out int output, out int input, out int application);

event ServiceStartedDelegate ServiceStarted;

Expand Down
67 changes: 33 additions & 34 deletions Desktop/Application/MaxMix/ViewModels/MainViewModel.cs
Expand Up @@ -210,7 +210,7 @@ private void OnDeviceCreated(object sender, int id, string displayName, int volu
return;

bool isCurrentMode = deviceFlow.ToDisplayMode() == m_SessionInfo.mode;
UpdateSessionData(id, isCurrentMode, true, deviceFlow.ToDisplayMode());
UpdateSessionData(id, isCurrentMode, true);
}

private void OnDeviceRemoved(object sender, int id, DeviceFlow deviceFlow)
Expand All @@ -219,7 +219,7 @@ private void OnDeviceRemoved(object sender, int id, DeviceFlow deviceFlow)
return;

bool isCurrentMode = deviceFlow.ToDisplayMode() == m_SessionInfo.mode;
UpdateSessionData(id, isCurrentMode, false, deviceFlow.ToDisplayMode());
UpdateSessionData(id, isCurrentMode, false);
}

private void OnAudioSessionCreated(object sender, int id, string displayName, int volume, bool isMuted)
Expand All @@ -228,7 +228,7 @@ private void OnAudioSessionCreated(object sender, int id, string displayName, in
return;

bool isCurrentMode = m_SessionInfo.mode == DisplayMode.MODE_APPLICATION || m_SessionInfo.mode == DisplayMode.MODE_GAME;
UpdateSessionData(id, isCurrentMode, true, DisplayMode.MODE_APPLICATION);
UpdateSessionData(id, isCurrentMode, true);
}

private void OnAudioSessionRemoved(object sender, int id)
Expand All @@ -237,32 +237,28 @@ private void OnAudioSessionRemoved(object sender, int id)
return;

bool isCurrentMode = m_SessionInfo.mode == DisplayMode.MODE_APPLICATION || m_SessionInfo.mode == DisplayMode.MODE_GAME;
UpdateSessionData(id, isCurrentMode, false, DisplayMode.MODE_APPLICATION);
UpdateSessionData(id, isCurrentMode, false);
}

private void UpdateSessionData(int id, bool updateCurrent, bool addition, DisplayMode updateMode)
private void UpdateSessionData(int id, bool IsCurrentMode, bool addition)
{
ISession[] sessions = _audioSessionService.GetSessions(updateMode);
if (updateMode == DisplayMode.MODE_INPUT)
m_SessionInfo.input = (byte)sessions.Length;
else if (updateMode == DisplayMode.MODE_OUTPUT)
m_SessionInfo.output = (byte)sessions.Length;
else
m_SessionInfo.application = (byte)sessions.Length;

if (updateCurrent)
_audioSessionService.GetSessionCounts(out var output, out var input, out int application);
m_SessionInfo.input = (byte)input;
m_SessionInfo.output = (byte)output;
m_SessionInfo.application = (byte)application;

if (IsCurrentMode)
{
ISession[] sessions = _audioSessionService.GetSessions(m_SessionInfo.mode);
// Do we still have sessions left?
if (sessions.Length == 0)
{
m_SessionInfo.mode = (DisplayMode)((int)m_SessionInfo.mode + 1 % (int)DisplayMode.MODE_MAX);
if (m_SessionInfo.mode == DisplayMode.MODE_SPLASH)
m_SessionInfo.mode = DisplayMode.MODE_OUTPUT;
m_SessionInfo.current = 0;

UpdateSessionData(int.MaxValue, updateCurrent, addition, m_SessionInfo.mode);

_communicationService.SendMessage(Command.SESSION_INFO, m_SessionInfo);
sessions = _audioSessionService.GetSessions(m_SessionInfo.mode);
m_SessionInfo.current = FindSessionIndex(sessions, x => x.IsDefault);
UpdateSessionData(int.MaxValue, IsCurrentMode, addition);
return;
}

Expand All @@ -272,7 +268,7 @@ private void UpdateSessionData(int id, bool updateCurrent, bool addition, Displa
if (addition)
m_SessionInfo.current++;
else if (id == currId)
m_SessionInfo.current = 0;
m_SessionInfo.current = FindSessionIndex(sessions, x => x.IsDefault);
else if (m_SessionInfo.current > 0)
m_SessionInfo.current--;
}
Expand Down Expand Up @@ -314,13 +310,16 @@ private void OnDeviceConnected()
OnSettingsChanged(null, null);
// Send device initial screen data

// NOTE: we can now have a setting to determin the initial screen
ISession[] sessions = _audioSessionService.GetSessions(DisplayMode.MODE_OUTPUT);
m_SessionInfo.mode = DisplayMode.MODE_OUTPUT;

// NOTE: we can now have a setting to determin the initial screen
ISession[] sessions = _audioSessionService.GetSessions(m_SessionInfo.mode);
_audioSessionService.GetSessionCounts(out var output, out var input, out int application);

m_SessionInfo.current = FindSessionIndex(sessions, x => x.IsDefault);
m_SessionInfo.output = (byte)sessions.Length;
m_SessionInfo.input = (byte)_audioSessionService.GetSessions(DisplayMode.MODE_INPUT).Length;
m_SessionInfo.application = (byte)_audioSessionService.GetSessions(DisplayMode.MODE_APPLICATION).Length;
m_SessionInfo.output = (byte)output;
m_SessionInfo.input = (byte)input;
m_SessionInfo.application = (byte)application;

UpdateAndFlushSessionData(sessions, true);

Expand All @@ -347,15 +346,14 @@ private void OnMessageRecieved(Command command, IMessage message)
// current, or mode
SessionInfo info = (SessionInfo)message;
m_SessionInfo.current = info.current;
bool updateIndexMap = info.mode != m_SessionInfo.mode;
bool updateCurrent = updateIndexMap && (info.mode == DisplayMode.MODE_INPUT || info.mode == DisplayMode.MODE_OUTPUT);
bool isNewMode = info.mode != m_SessionInfo.mode;
m_SessionInfo.mode = info.mode;

ISession[] sessions = _audioSessionService.GetSessions(m_SessionInfo.mode);
if (updateCurrent)
if (isNewMode)
m_SessionInfo.current = FindSessionIndex(sessions, x => x.IsDefault);
UpdateAndFlushSessionData(sessions, updateIndexMap);
if (updateCurrent)
UpdateAndFlushSessionData(sessions, isNewMode);
if (isNewMode)
_communicationService.SendMessage(Command.SESSION_INFO, m_SessionInfo);
}
else if (command == Command.ALTERNATE_SESSION)
Expand All @@ -376,16 +374,17 @@ byte FindSessionIndex(ISession[] sessions, Predicate<ISession> match)

void UpdateAndFlushSessionData(ISession[] data, bool updateIndexMap = false)
{
int index = m_SessionInfo.current;
if (updateIndexMap)
PopulateIndexToIdMap(data);

int index = m_SessionInfo.current;
ComputeIndexes(index, out int prevIndex, out int nextIndex);

// The device can easily spin the encoder faster than we can respond via Serial.
// So just flush all 3 sessions to the device to ensure it will have fresh data when it stops, whatever it stops on.
m_Sessions[(int)SessionIndex.INDEX_CURRENT] = data[index].ToSessionData(index);
m_Sessions[(int)SessionIndex.INDEX_PREVIOUS] = data[prevIndex].ToSessionData(prevIndex);
m_Sessions[(int)SessionIndex.INDEX_NEXT] = data[nextIndex].ToSessionData(nextIndex);
m_Sessions[(int)SessionIndex.INDEX_CURRENT] = data.ToSessionData(index);
m_Sessions[(int)SessionIndex.INDEX_PREVIOUS] = data.ToSessionData(prevIndex);
m_Sessions[(int)SessionIndex.INDEX_NEXT] = data.ToSessionData(nextIndex);
_communicationService.SendMessage(Command.CURRENT_SESSION, m_Sessions[(int)SessionIndex.INDEX_CURRENT]);
_communicationService.SendMessage(Command.PREVIOUS_SESSION, m_Sessions[(int)SessionIndex.INDEX_PREVIOUS]);
_communicationService.SendMessage(Command.NEXT_SESSION, m_Sessions[(int)SessionIndex.INDEX_NEXT]);
Expand Down

0 comments on commit c053ea5

Please sign in to comment.