-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathBassCdStreamInput.cs
153 lines (137 loc) · 5.01 KB
/
BassCdStreamInput.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using FoxTunes.Interfaces;
using ManagedBass;
using ManagedBass.Gapless;
using System.Linq;
using System.Collections.Generic;
using System;
using ManagedBass.Cd;
namespace FoxTunes
{
public class BassCdStreamInput : BassStreamInput
{
public BassCdStreamInput(BassCdBehaviour behaviour, int drive, IBassStreamPipeline pipeline, BassFlags flags) : base(pipeline, flags)
{
this.Behaviour = behaviour;
this.Drive = drive;
}
public override IEnumerable<Type> SupportedProviders
{
get
{
return new[]
{
typeof(BassCdStreamProvider)
};
}
}
public override string Name
{
get
{
return "CD";
}
}
public override string Description
{
get
{
var rate = default(int);
var channels = default(int);
var flags = default(BassFlags);
if (!this.GetFormat(out rate, out channels, out flags))
{
rate = 0;
channels = 0;
flags = BassFlags.Default;
}
return string.Format(
"{0} ({1}/{2}/{3})",
this.Name,
BassUtils.DepthDescription(flags),
MetaDataInfo.SampleRateDescription(rate),
MetaDataInfo.ChannelDescription(channels)
);
}
}
public BassCdBehaviour Behaviour { get; private set; }
public int Drive { get; private set; }
public override int ChannelHandle { get; protected set; }
public override IEnumerable<int> Queue
{
get
{
var count = default(int);
return BassGapless.GetChannels(out count);
}
}
public bool SetTrack(int track, out int channelHandle)
{
channelHandle = this.Queue.FirstOrDefault();
if (channelHandle == 0)
{
return false;
}
if (BassCd.StreamGetTrack(channelHandle) != track)
{
Logger.Write(this, LogLevel.Debug, "Switching CD track: {0}", track);
BassUtils.OK(BassCd.StreamSetTrack(channelHandle, track));
}
return true;
}
public override void Connect(BassOutputStream stream)
{
BassUtils.OK(BassGapless.SetConfig(BassGaplessAttriubute.KeepAlive, true));
BassUtils.OK(BassGapless.SetConfig(BassGaplessAttriubute.RecycleStream, true));
BassUtils.OK(BassGapless.ChannelEnqueue(stream.ChannelHandle));
BassUtils.OK(BassGapless.Cd.Enable(this.Drive, stream.Flags));
Logger.Write(this, LogLevel.Debug, "Creating BASS GAPLESS stream with rate {0} and {1} channels.", stream.Rate, stream.Channels);
this.ChannelHandle = BassGapless.StreamCreate(stream.Rate, stream.Channels, stream.Flags);
if (this.ChannelHandle == 0)
{
BassUtils.Throw();
}
}
public override bool Contains(BassOutputStream stream)
{
return this.Queue.Contains(stream.ChannelHandle);
}
public override int Position(BassOutputStream stream)
{
return POSITION_INDETERMINATE;
}
public override bool Add(BassOutputStream stream, Action<BassOutputStream> callBack)
{
if (!this.Contains(stream))
{
//I think this happens when the CD has ended.
BassUtils.OK(BassGapless.ChannelEnqueue(stream.ChannelHandle));
}
return false;
}
public override bool Remove(BassOutputStream stream, Action<BassOutputStream> callBack)
{
return false;
}
public override void Reset()
{
Logger.Write(this, LogLevel.Debug, "Resetting the queue.");
foreach (var channelHandle in this.Queue)
{
Logger.Write(this, LogLevel.Debug, "Removing stream from the queue: {0}", channelHandle);
BassGapless.ChannelRemove(channelHandle);
Bass.StreamFree(channelHandle);
}
}
protected override void OnDisposing()
{
if (this.ChannelHandle != 0)
{
this.Reset();
Logger.Write(this, LogLevel.Debug, "Freeing BASS GAPLESS stream: {0}", this.ChannelHandle);
Bass.StreamFree(this.ChannelHandle); //Not checking result code as it contains an error if the application is shutting down.
}
BassGapless.Cd.Disable();
BassCd.Release(this.Drive);
}
}
}