~njh-aelius/maxosx/submit-discid

598 by stephen_booth
Renamed directory
1
/*
2
 *  $Id$
3
 *
1060 by stephen_booth
Updated copyright for 2007
4
 *  Copyright (C) 2005 - 2007 Stephen F. Booth <me@sbooth.org>
598 by stephen_booth
Renamed directory
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
21
#import "CompactDisc.h"
22
23
#import "Drive.h"
616 by stephen_booth
Log detection of multisession disc
24
#import "LogController.h"
894 by stephen_booth
Replaced FreeDB with MusicBrainz
25
1154 by stephen_booth
Use libdiscid
26
#include <discid/discid.h>
894 by stephen_booth
Replaced FreeDB with MusicBrainz
27
#include <IOKit/storage/IOCDTypes.h>
598 by stephen_booth
Renamed directory
28
29
@implementation CompactDisc
30
31
- (id) initWithDeviceName:(NSString *)deviceName;
32
{
33
	if((self = [super init])) {
34
		unsigned				i;
610 by stephen_booth
Fix for enhanced/multisession CDs
35
		unsigned				session			= 1;
598 by stephen_booth
Renamed directory
36
		unsigned long			discLength		= 150;
37
		Drive					*drive			= nil;
38
		TrackDescriptor			*track			= nil;
39
		NSMutableDictionary		*trackInfo		= nil;
40
		NSString				*ISRC			= nil;
41
42
		_deviceName		= [deviceName retain];
43
44
		// To avoid keeping an open file descriptor, read the disc's properties from the drive
45
		// and store them in our ivars
870 by stephen_booth
Code cleanup
46
		drive = [[Drive alloc] initWithDeviceName:[self deviceName]];
610 by stephen_booth
Fix for enhanced/multisession CDs
47
48
		// Is this is a multisession disc?
1154 by stephen_booth
Use libdiscid
49
		if([drive lastSession] - [drive firstSession] > 0)
616 by stephen_booth
Log detection of multisession disc
50
			[LogController logMessage:NSLocalizedStringFromTable(@"Multisession disc detected", @"Log", @"")];
598 by stephen_booth
Renamed directory
51
		
894 by stephen_booth
Replaced FreeDB with MusicBrainz
52
		// Use first session for now
53
		session			= 1;
54
		
598 by stephen_booth
Renamed directory
55
		// Disc information
610 by stephen_booth
Fix for enhanced/multisession CDs
56
		_firstSector	= [drive firstSectorForSession:session];
57
		_lastSector		= [drive lastSectorForSession:session];
598 by stephen_booth
Renamed directory
58
894 by stephen_booth
Replaced FreeDB with MusicBrainz
59
		_leadOut		= [drive leadOutForSession:session];
60
61
		_MCN			= [[drive readMCN] retain];
598 by stephen_booth
Renamed directory
62
		
63
		// Iterate through the tracks and get their information
894 by stephen_booth
Replaced FreeDB with MusicBrainz
64
		_tracks			= [[NSMutableArray alloc] init];
598 by stephen_booth
Renamed directory
65
		
610 by stephen_booth
Fix for enhanced/multisession CDs
66
		for(i = [drive firstTrackForSession:session]; i <= [drive lastTrackForSession:session]; ++i) {
598 by stephen_booth
Renamed directory
67
68
			track = [drive trackNumber:i];
69
			
70
			trackInfo = [NSMutableDictionary dictionaryWithCapacity:6];
71
		
72
			[trackInfo setObject:[NSNumber numberWithUnsignedInt:i] forKey:@"number"];
73
74
			[trackInfo setObject:[NSNumber numberWithUnsignedInt:[drive firstSectorForTrack:i]] forKey:@"firstSector"];
75
			[trackInfo setObject:[NSNumber numberWithUnsignedInt:[drive lastSectorForTrack:i]] forKey:@"lastSector"];
76
77
			[trackInfo setObject:[NSNumber numberWithUnsignedInt:[track channels]] forKey:@"channels"];
78
79
			[trackInfo setObject:[NSNumber numberWithBool:[track preEmphasis]] forKey:@"preEmphasis"];
80
			[trackInfo setObject:[NSNumber numberWithBool:[track copyPermitted]] forKey:@"allowsDigitalCopy"];
81
			[trackInfo setObject:[NSNumber numberWithBool:[track dataTrack]] forKey:@"dataTrack"];
82
83
			ISRC = [drive readISRC:i];
1154 by stephen_booth
Use libdiscid
84
			if(nil != ISRC)
598 by stephen_booth
Renamed directory
85
				[trackInfo setObject:ISRC forKey:@"ISRC"];
610 by stephen_booth
Fix for enhanced/multisession CDs
86
598 by stephen_booth
Renamed directory
87
			[_tracks addObject:trackInfo];
88
		}
89
		
1154 by stephen_booth
Use libdiscid
90
		for(i = 0; i < [self countOfTracks]; ++i)
598 by stephen_booth
Renamed directory
91
			discLength += [self lastSectorForTrack:i] - [self firstSectorForTrack:i] + 1;
92
		_length = (unsigned) (60 * (discLength / (60 * 75))) + (unsigned)((discLength / 75) % 60);
870 by stephen_booth
Code cleanup
93
		
94
		[drive release];
894 by stephen_booth
Replaced FreeDB with MusicBrainz
95
				
598 by stephen_booth
Renamed directory
96
		return self;
97
	}
98
	
99
	return nil;
100
}
101
102
- (void) dealloc
103
{
716 by stephen_booth
Improved dealloc
104
	[_deviceName release];		_deviceName = nil;
105
	[_tracks release];			_tracks = nil;
106
	[_MCN release];				_MCN = nil;
894 by stephen_booth
Replaced FreeDB with MusicBrainz
107
598 by stephen_booth
Renamed directory
108
	[super dealloc];
109
}
110
731 by stephen_booth
Improved accessors
111
- (NSString *)		deviceName								{ return [[_deviceName retain] autorelease]; }
598 by stephen_booth
Renamed directory
112
731 by stephen_booth
Improved accessors
113
- (NSString *)		MCN										{ return [[_MCN retain] autorelease]; }
598 by stephen_booth
Renamed directory
114
115
- (unsigned)		firstSector								{ return _firstSector; }
116
- (unsigned)		lastSector								{ return _lastSector; }
117
894 by stephen_booth
Replaced FreeDB with MusicBrainz
118
- (unsigned)		leadOut									{ return _leadOut; }
119
598 by stephen_booth
Renamed directory
120
- (unsigned)		firstSectorForTrack:(unsigned)track		{ return [[[self objectInTracksAtIndex:track] objectForKey:@"firstSector"] unsignedIntValue]; }
121
- (unsigned)		lastSectorForTrack:(unsigned)track		{ return [[[self objectInTracksAtIndex:track] objectForKey:@"lastSector"] unsignedIntValue]; }
122
123
- (unsigned)		channelsForTrack:(unsigned)track		{ return [[[self objectInTracksAtIndex:track] objectForKey:@"channels"] unsignedIntValue]; }
124
125
- (BOOL)			trackHasPreEmphasis:(unsigned)track		{ return [[[self objectInTracksAtIndex:track] objectForKey:@"hasPreEmphasis"] boolValue]; }
126
- (BOOL)			trackAllowsDigitalCopy:(unsigned)track	{ return [[[self objectInTracksAtIndex:track] objectForKey:@"allowsDigitalCopy"] boolValue]; }
614 by stephen_booth
Got rid of containsAudio method; use dataTrack instead
127
- (BOOL)			trackContainsData:(unsigned)track		{ return [[[self objectInTracksAtIndex:track] objectForKey:@"dataTrack"] boolValue]; }
598 by stephen_booth
Renamed directory
128
129
- (NSString *)		ISRCForTrack:(unsigned)track			{ return [[self objectInTracksAtIndex:track] objectForKey:@"ISRC"]; }
130
1297 by Nicholas J Humfrey
Added support for submitting disc ids
131
132
- (DiscId *) discIdObj
133
{
134
	DiscId *discID = discid_new();
135
	if(NULL == discID)
136
		return NULL;
137
	
138
	// zero is lead out
139
	int offsets[100];
140
	offsets[0] = [self leadOut] + 150;
141
	
142
	unsigned i;
143
	for(i = 0; i < [self countOfTracks]; ++i)
144
		offsets[1 + i] = [self firstSectorForTrack:i] + 150;
145
	
146
	int result = discid_put(discID, 1, [self countOfTracks], offsets);
147
	if(result) {
148
		return discID;
149
	} else {
150
		discid_free(discID);
151
		return NULL;
152
	}
153
	
154
}
155
894 by stephen_booth
Replaced FreeDB with MusicBrainz
156
- (NSString *) discID
157
{
1154 by stephen_booth
Use libdiscid
158
	NSString *musicBrainzDiscID = nil;
159
	
1297 by Nicholas J Humfrey
Added support for submitting disc ids
160
	DiscId *discID = [self discIdObj];
1154 by stephen_booth
Use libdiscid
161
	if(NULL == discID)
162
		return nil;
163
	
1297 by Nicholas J Humfrey
Added support for submitting disc ids
164
	musicBrainzDiscID = [NSString stringWithCString:discid_get_id(discID) encoding:NSASCIIStringEncoding];
1154 by stephen_booth
Use libdiscid
165
		
166
	discid_free(discID);
167
	
168
	return [[musicBrainzDiscID retain] autorelease];
894 by stephen_booth
Replaced FreeDB with MusicBrainz
169
}
170
1240 by stephen_booth
Added freeDBDiscID method
171
- (NSString *) freeDBDiscID
172
{
173
	NSString *freeDBDiscID = nil;
174
	
1297 by Nicholas J Humfrey
Added support for submitting disc ids
175
	DiscId *discID = [self discIdObj];
1240 by stephen_booth
Added freeDBDiscID method
176
	if(NULL == discID)
177
		return nil;
178
	
1297 by Nicholas J Humfrey
Added support for submitting disc ids
179
	freeDBDiscID = [NSString stringWithCString:discid_get_freedb_id(discID) encoding:NSASCIIStringEncoding];
1240 by stephen_booth
Added freeDBDiscID method
180
	
181
	discid_free(discID);
182
	
183
	return [[freeDBDiscID retain] autorelease];
184
}
185
1297 by Nicholas J Humfrey
Added support for submitting disc ids
186
- (NSURL *) submissionURL
187
{
188
	NSURL *submissionURL = nil;
189
	
190
	DiscId *discID = [self discIdObj];
191
	if(NULL == discID)
192
		return nil;
193
	
194
	submissionURL = [NSURL URLWithString:[NSString stringWithCString:discid_get_submission_url(discID) encoding:NSASCIIStringEncoding]];
195
	
196
	discid_free(discID);
197
	
198
	return [[submissionURL retain] autorelease];
199
}
200
598 by stephen_booth
Renamed directory
201
- (unsigned)		length									{ return _length; }
202
203
// KVC
204
- (unsigned)		countOfTracks							{ return [_tracks count]; }
894 by stephen_booth
Replaced FreeDB with MusicBrainz
205
- (NSDictionary *)	objectInTracksAtIndex:(unsigned)index	{ return [_tracks objectAtIndex:index]; }
598 by stephen_booth
Renamed directory
206
207
@end