|
1 | 1 | // |
2 | | -// Copyright (c) 2006-2024 Stephen F. Booth <[email protected]> |
| 2 | +// Copyright (c) 2006-2025 Stephen F. Booth <[email protected]> |
3 | 3 | // Part of https://github.com/sbooth/SFBAudioEngine |
4 | 4 | // MIT license |
5 | 5 | // |
@@ -59,95 +59,111 @@ + (BOOL)testFileHandle:(NSFileHandle *)fileHandle formatIsSupported:(SFBTernaryT |
59 | 59 |
|
60 | 60 | - (BOOL)readPropertiesAndMetadataReturningError:(NSError **)error |
61 | 61 | { |
62 | | - TagLib::FileStream stream(self.url.fileSystemRepresentation, true); |
63 | | - if(!stream.isOpen()) { |
64 | | - if(error) |
65 | | - *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
66 | | - code:SFBAudioFileErrorCodeInputOutput |
67 | | - descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” could not be opened for reading.", @"") |
68 | | - url:self.url |
69 | | - failureReason:NSLocalizedString(@"Input/output error", @"") |
70 | | - recoverySuggestion:NSLocalizedString(@"The file may have been renamed, moved, deleted, or you may not have appropriate permissions.", @"")]; |
71 | | - return NO; |
| 62 | + try { |
| 63 | + TagLib::FileStream stream(self.url.fileSystemRepresentation, true); |
| 64 | + if(!stream.isOpen()) { |
| 65 | + if(error) |
| 66 | + *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
| 67 | + code:SFBAudioFileErrorCodeInputOutput |
| 68 | + descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” could not be opened for reading.", @"") |
| 69 | + url:self.url |
| 70 | + failureReason:NSLocalizedString(@"Input/output error", @"") |
| 71 | + recoverySuggestion:NSLocalizedString(@"The file may have been renamed, moved, deleted, or you may not have appropriate permissions.", @"")]; |
| 72 | + return NO; |
| 73 | + } |
| 74 | + |
| 75 | + TagLib::DSDIFF::File file(&stream); |
| 76 | + if(!file.isValid()) { |
| 77 | + if(error) |
| 78 | + *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
| 79 | + code:SFBAudioFileErrorCodeInvalidFormat |
| 80 | + descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” is not a valid DSD Interchange file.", @"") |
| 81 | + url:self.url |
| 82 | + failureReason:NSLocalizedString(@"Not a DSD Interchange file", @"") |
| 83 | + recoverySuggestion:NSLocalizedString(@"The file's extension may not match the file's type.", @"")]; |
| 84 | + return NO; |
| 85 | + } |
| 86 | + |
| 87 | + NSMutableDictionary *propertiesDictionary = [NSMutableDictionary dictionaryWithObject:@"DSD Interchange" forKey:SFBAudioPropertiesKeyFormatName]; |
| 88 | + if(file.audioProperties()) { |
| 89 | + auto properties = file.audioProperties(); |
| 90 | + SFB::Audio::AddAudioPropertiesToDictionary(properties, propertiesDictionary); |
| 91 | + |
| 92 | + if(properties->bitsPerSample()) |
| 93 | + propertiesDictionary[SFBAudioPropertiesKeyBitDepth] = @(properties->bitsPerSample()); |
| 94 | + if(properties->sampleCount()) |
| 95 | + propertiesDictionary[SFBAudioPropertiesKeyFrameLength] = @(properties->sampleCount()); |
| 96 | + } |
| 97 | + |
| 98 | + SFBAudioMetadata *metadata = [[SFBAudioMetadata alloc] init]; |
| 99 | + if(file.hasDIINTag()) |
| 100 | + [metadata addMetadataFromTagLibTag:file.DIINTag()]; |
| 101 | + |
| 102 | + if(file.hasID3v2Tag()) |
| 103 | + [metadata addMetadataFromTagLibID3v2Tag:file.ID3v2Tag()]; |
| 104 | + |
| 105 | + self.properties = [[SFBAudioProperties alloc] initWithDictionaryRepresentation:propertiesDictionary]; |
| 106 | + self.metadata = metadata; |
| 107 | + |
| 108 | + return YES; |
72 | 109 | } |
73 | | - |
74 | | - TagLib::DSDIFF::File file(&stream); |
75 | | - if(!file.isValid()) { |
| 110 | + catch(const std::exception& e) { |
| 111 | + os_log_error(gSFBAudioFileLog, "Error reading DSD Interchange properties and metadata: %{public}s", e.what()); |
76 | 112 | if(error) |
77 | | - *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
78 | | - code:SFBAudioFileErrorCodeInvalidFormat |
79 | | - descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” is not a valid DSD Interchange file.", @"") |
80 | | - url:self.url |
81 | | - failureReason:NSLocalizedString(@"Not a DSD Interchange file", @"") |
82 | | - recoverySuggestion:NSLocalizedString(@"The file's extension may not match the file's type.", @"")]; |
| 113 | + *error = [NSError errorWithDomain:SFBAudioFileErrorDomain code:SFBAudioFileErrorCodeInternalError userInfo:nil]; |
83 | 114 | return NO; |
84 | 115 | } |
85 | | - |
86 | | - NSMutableDictionary *propertiesDictionary = [NSMutableDictionary dictionaryWithObject:@"DSD Interchange" forKey:SFBAudioPropertiesKeyFormatName]; |
87 | | - if(file.audioProperties()) { |
88 | | - auto properties = file.audioProperties(); |
89 | | - SFB::Audio::AddAudioPropertiesToDictionary(properties, propertiesDictionary); |
90 | | - |
91 | | - if(properties->bitsPerSample()) |
92 | | - propertiesDictionary[SFBAudioPropertiesKeyBitDepth] = @(properties->bitsPerSample()); |
93 | | - if(properties->sampleCount()) |
94 | | - propertiesDictionary[SFBAudioPropertiesKeyFrameLength] = @(properties->sampleCount()); |
95 | | - } |
96 | | - |
97 | | - SFBAudioMetadata *metadata = [[SFBAudioMetadata alloc] init]; |
98 | | - if(file.hasDIINTag()) |
99 | | - [metadata addMetadataFromTagLibTag:file.DIINTag()]; |
100 | | - |
101 | | - if(file.hasID3v2Tag()) |
102 | | - [metadata addMetadataFromTagLibID3v2Tag:file.ID3v2Tag()]; |
103 | | - |
104 | | - self.properties = [[SFBAudioProperties alloc] initWithDictionaryRepresentation:propertiesDictionary]; |
105 | | - self.metadata = metadata; |
106 | | - return YES; |
107 | 116 | } |
108 | 117 |
|
109 | 118 | - (BOOL)writeMetadataReturningError:(NSError **)error |
110 | 119 | { |
111 | | - TagLib::FileStream stream(self.url.fileSystemRepresentation); |
112 | | - if(!stream.isOpen()) { |
113 | | - if(error) |
114 | | - *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
115 | | - code:SFBAudioFileErrorCodeInputOutput |
116 | | - descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” could not be opened for writing.", @"") |
117 | | - url:self.url |
118 | | - failureReason:NSLocalizedString(@"Input/output error", @"") |
119 | | - recoverySuggestion:NSLocalizedString(@"The file may have been renamed, moved, deleted, or you may not have appropriate permissions.", @"")]; |
120 | | - return NO; |
121 | | - } |
122 | | - |
123 | | - TagLib::DSDIFF::File file(&stream, false); |
124 | | - if(!file.isValid()) { |
125 | | - if(error) |
126 | | - *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
127 | | - code:SFBAudioFileErrorCodeInvalidFormat |
128 | | - descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” is not a valid DSD Interchange file.", @"") |
129 | | - url:self.url |
130 | | - failureReason:NSLocalizedString(@"Not a DSD Interchange file", @"") |
131 | | - recoverySuggestion:NSLocalizedString(@"The file's extension may not match the file's type.", @"")]; |
132 | | - return NO; |
| 120 | + try { |
| 121 | + TagLib::FileStream stream(self.url.fileSystemRepresentation); |
| 122 | + if(!stream.isOpen()) { |
| 123 | + if(error) |
| 124 | + *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
| 125 | + code:SFBAudioFileErrorCodeInputOutput |
| 126 | + descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” could not be opened for writing.", @"") |
| 127 | + url:self.url |
| 128 | + failureReason:NSLocalizedString(@"Input/output error", @"") |
| 129 | + recoverySuggestion:NSLocalizedString(@"The file may have been renamed, moved, deleted, or you may not have appropriate permissions.", @"")]; |
| 130 | + return NO; |
| 131 | + } |
| 132 | + |
| 133 | + TagLib::DSDIFF::File file(&stream, false); |
| 134 | + if(!file.isValid()) { |
| 135 | + if(error) |
| 136 | + *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
| 137 | + code:SFBAudioFileErrorCodeInvalidFormat |
| 138 | + descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” is not a valid DSD Interchange file.", @"") |
| 139 | + url:self.url |
| 140 | + failureReason:NSLocalizedString(@"Not a DSD Interchange file", @"") |
| 141 | + recoverySuggestion:NSLocalizedString(@"The file's extension may not match the file's type.", @"")]; |
| 142 | + return NO; |
| 143 | + } |
| 144 | + |
| 145 | + SFB::Audio::SetTagFromMetadata(self.metadata, file.tag()); |
| 146 | + SFB::Audio::SetID3v2TagFromMetadata(self.metadata, file.ID3v2Tag()); |
| 147 | + |
| 148 | + if(!file.save()) { |
| 149 | + if(error) |
| 150 | + *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
| 151 | + code:SFBAudioFileErrorCodeInputOutput |
| 152 | + descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” could not be saved.", @"") |
| 153 | + url:self.url |
| 154 | + failureReason:NSLocalizedString(@"Unable to write metadata", @"") |
| 155 | + recoverySuggestion:NSLocalizedString(@"The file's extension may not match the file's type.", @"")]; |
| 156 | + return NO; |
| 157 | + } |
| 158 | + |
| 159 | + return YES; |
133 | 160 | } |
134 | | - |
135 | | - SFB::Audio::SetTagFromMetadata(self.metadata, file.tag()); |
136 | | - SFB::Audio::SetID3v2TagFromMetadata(self.metadata, file.ID3v2Tag()); |
137 | | - |
138 | | - if(!file.save()) { |
| 161 | + catch(const std::exception& e) { |
| 162 | + os_log_error(gSFBAudioFileLog, "Error writing DSD Interchange metadata: %{public}s", e.what()); |
139 | 163 | if(error) |
140 | | - *error = [NSError SFB_errorWithDomain:SFBAudioFileErrorDomain |
141 | | - code:SFBAudioFileErrorCodeInputOutput |
142 | | - descriptionFormatStringForURL:NSLocalizedString(@"The file “%@” could not be saved.", @"") |
143 | | - url:self.url |
144 | | - failureReason:NSLocalizedString(@"Unable to write metadata", @"") |
145 | | - recoverySuggestion:NSLocalizedString(@"The file's extension may not match the file's type.", @"")]; |
| 164 | + *error = [NSError errorWithDomain:SFBAudioFileErrorDomain code:SFBAudioFileErrorCodeInternalError userInfo:nil]; |
146 | 165 | return NO; |
147 | 166 | } |
148 | | - |
149 | | - |
150 | | - return YES; |
151 | 167 | } |
152 | 168 |
|
153 | 169 | @end |
0 commit comments