5
// Aaron Bockover <abockover@novell.com>
6
// Alex Launi <alex.launi@canonical.com>
8
// Copyright (C) 2008 Novell, Inc.
10
// Permission is hereby granted, free of charge, to any person obtaining
11
// a copy of this software and associated documentation files (the
12
// "Software"), to deal in the Software without restriction, including
13
// without limitation the rights to use, copy, modify, merge, publish,
14
// distribute, sublicense, and/or sell copies of the Software, and to
15
// permit persons to whom the Software is furnished to do so, subject to
16
// the following conditions:
18
// The above copyright notice and this permission notice shall be
19
// included in all copies or substantial portions of the Software.
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
using System.Threading;
32
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
40
using Banshee.Hardware;
41
using Banshee.Collection;
42
using Banshee.Collection.Database;
44
namespace Banshee.OpticalDisc.AudioCd
46
public class AudioCdDiscModel : DiscModel
48
// 44.1 kHz sample rate * 16 bit channel resolution * 2 channels (stereo)
49
private const long PCM_FACTOR = 176400;
51
public event EventHandler MetadataQueryStarted;
52
public event EventHandler MetadataQueryFinished;
53
public event EventHandler EnabledCountChanged;
55
private bool metadata_query_success;
56
private DateTime metadata_query_start_time;
58
public bool MetadataQuerySuccess {
59
get { return metadata_query_success; }
62
private TimeSpan duration;
63
public TimeSpan Duration {
64
get { return duration; }
67
private long file_size;
68
public long FileSize {
69
get { return file_size; }
72
public AudioCdDiscModel (IDiscVolume volume)
75
disc_title = Catalog.GetString ("Audio CD");
77
MusicBrainzService.UserAgent = Banshee.Web.Browser.UserAgent;
80
public void NotifyUpdated ()
85
public override void LoadModelFromDisc ()
89
LocalDisc mb_disc = LocalDisc.GetFromDevice (Volume.DeviceNode);
90
if (mb_disc == null) {
91
throw new ApplicationException ("Could not read contents of the disc. Platform may not be supported.");
94
TimeSpan[] durations = mb_disc.GetTrackDurations ();
95
for (int i = 0, n = durations.Length; i < n; i++) {
96
AudioCdTrackInfo track = new AudioCdTrackInfo (this, Volume.DeviceNode, i);
97
track.TrackNumber = i + 1;
100
track.Duration = durations[i];
101
track.ArtistName = Catalog.GetString ("Unknown Artist");
102
track.AlbumTitle = Catalog.GetString ("Unknown Album");
103
track.TrackTitle = String.Format (Catalog.GetString ("Track {0}"), track.TrackNumber);
104
track.FileSize = PCM_FACTOR * (uint)track.Duration.TotalSeconds;
107
duration += track.Duration;
108
file_size += track.FileSize;
111
EnabledCount = Count;
115
ThreadPool.QueueUserWorkItem (LoadDiscMetadata, mb_disc);
118
private void LoadDiscMetadata (object state)
121
LocalDisc mb_disc = (LocalDisc)state;
123
OnMetadataQueryStarted (mb_disc);
125
Release release = Release.Query (mb_disc).First ();
127
if (release == null || release.Score < 100) {
128
OnMetadataQueryFinished (false);
132
var tracks = release.GetTracks ();
133
if (tracks.Count != Count) {
134
OnMetadataQueryFinished (false);
138
disc_title = release.GetTitle ();
143
foreach (Disc disc in release.GetDiscs ()) {
145
if (disc.Id == mb_disc.Id) {
150
DateTime release_date = DateTime.MaxValue;
152
foreach (Event release_event in release.GetEvents ()) {
153
if (release_event.Date != null) {
155
// Handle "YYYY" dates
156
var date_str = release_event.Date;
157
DateTime date = DateTime.Parse (
158
date_str.Length > 4 ? date_str : date_str + "-01",
159
ApplicationContext.InternalCultureInfo
162
if (date < release_date) {
170
DatabaseArtistInfo artist = new DatabaseArtistInfo ();
171
var mb_artist = release.GetArtist ();
172
artist.Name = mb_artist.GetName ();
173
artist.NameSort = mb_artist.GetSortName ();
174
artist.MusicBrainzId = mb_artist.Id;
175
bool is_compilation = false;
177
DatabaseAlbumInfo album = new DatabaseAlbumInfo ();
178
album.Title = disc_title;
179
album.ArtistName = artist.Name;
180
album.MusicBrainzId = release.Id;
181
album.ReleaseDate = release_date == DateTime.MaxValue ? DateTime.MinValue : release_date;
184
foreach (Track track in tracks) {
185
AudioCdTrackInfo model_track = (AudioCdTrackInfo)this[i++];
186
var mb_track_artist = track.GetArtist ();
188
model_track.MusicBrainzId = track.Id;
189
model_track.TrackTitle = track.GetTitle ();
190
model_track.ArtistName = mb_track_artist.GetName ();
191
model_track.AlbumTitle = disc_title;
192
model_track.DiscNumber = disc_number;
193
model_track.Album = album;
195
model_track.Artist = new DatabaseArtistInfo ();
196
model_track.Artist.Name = model_track.ArtistName;
197
model_track.Artist.NameSort = mb_track_artist.GetSortName ();
198
model_track.Artist.MusicBrainzId = mb_track_artist.Id;
200
if (release_date != DateTime.MinValue) {
201
model_track.Year = release_date.Year;
204
if (!is_compilation && mb_track_artist.Id != artist.MusicBrainzId) {
205
is_compilation = true;
209
if (is_compilation) {
210
album.IsCompilation = true;
211
for (i = 0; i < tracks.Count; i++) {
212
AudioCdTrackInfo model_track = (AudioCdTrackInfo)this[i];
213
model_track.IsCompilation = true;
214
model_track.AlbumArtist = artist.Name;
215
model_track.AlbumArtistSort = artist.NameSort;
219
OnMetadataQueryFinished (true);
220
} catch (Exception ex) {
221
Log.DebugException (ex);
222
OnMetadataQueryFinished (false);
226
private void OnMetadataQueryStarted (LocalDisc mb_disc)
228
metadata_query_success = false;
229
metadata_query_start_time = DateTime.Now;
230
Log.InformationFormat ("Querying MusicBrainz for Disc Release ({0})", mb_disc.Id);
232
ThreadAssist.ProxyToMain (delegate {
233
EventHandler handler = MetadataQueryStarted;
234
if (handler != null) {
235
handler (this, EventArgs.Empty);
240
private void OnMetadataQueryFinished (bool success)
242
metadata_query_success = success;
243
Log.InformationFormat ("Query finished (success: {0}, {1} seconds)",
244
success, (DateTime.Now - metadata_query_start_time).TotalSeconds);
246
ThreadAssist.ProxyToMain (delegate {
249
EventHandler handler = MetadataQueryFinished;
250
if (handler != null) {
251
handler (this, EventArgs.Empty);
256
private void OnEnabledCountChanged ()
258
EventHandler handler = EnabledCountChanged;
259
if (handler != null) {
260
handler (this, EventArgs.Empty);
264
private string disc_title;
265
public override string Title {
266
get { return disc_title; }
269
private int enabled_count;
270
public int EnabledCount {
271
get { return enabled_count; }
273
enabled_count = value;
274
OnEnabledCountChanged ();