mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Wavpack output can now have tags and embedded cue sheet.
This commit is contained in:
@@ -128,7 +128,12 @@ namespace APEDotNet {
|
|||||||
|
|
||||||
property NameValueCollection^ Tags {
|
property NameValueCollection^ Tags {
|
||||||
NameValueCollection^ get () {
|
NameValueCollection^ get () {
|
||||||
if (!_tags) _tags = (gcnew APETagDotNet (_path, true))->GetStringTags (true);
|
if (!_tags)
|
||||||
|
{
|
||||||
|
APETagDotNet^ apeTag = gcnew APETagDotNet (_path, true, true);
|
||||||
|
_tags = apeTag->GetStringTags (true);
|
||||||
|
apeTag->Close ();
|
||||||
|
}
|
||||||
return _tags;
|
return _tags;
|
||||||
}
|
}
|
||||||
void set (NameValueCollection ^tags) {
|
void set (NameValueCollection ^tags) {
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ namespace APETagsDotNet
|
|||||||
{
|
{
|
||||||
LittleEndian.Write32(pBuffer, pos, _fieldValue.Length);
|
LittleEndian.Write32(pBuffer, pos, _fieldValue.Length);
|
||||||
LittleEndian.Write32(pBuffer, pos + 4, _fieldFlags);
|
LittleEndian.Write32(pBuffer, pos + 4, _fieldFlags);
|
||||||
Array.Copy (new ASCIIEncoding().GetBytes(_fieldName), pBuffer, pos + 8);
|
Array.Copy(new ASCIIEncoding().GetBytes(_fieldName), 0, pBuffer, pos + 8, _fieldName.Length);
|
||||||
pBuffer[pos + 8 + _fieldName.Length] = 0;
|
pBuffer[pos + 8 + _fieldName.Length] = 0;
|
||||||
Array.Copy(_fieldValue, pBuffer, pos + 8 + _fieldName.Length + 1);
|
Array.Copy(_fieldValue, 0, pBuffer, pos + 8 + _fieldName.Length + 1, _fieldValue.Length);
|
||||||
return GetFieldSize();
|
return GetFieldSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,9 +173,9 @@ namespace APETagsDotNet
|
|||||||
// create an APE tags object
|
// create an APE tags object
|
||||||
// bAnalyze determines whether it will analyze immediately or on the first request
|
// bAnalyze determines whether it will analyze immediately or on the first request
|
||||||
// be careful with multiple threads / file pointer movement if you don't analyze immediately
|
// be careful with multiple threads / file pointer movement if you don't analyze immediately
|
||||||
public APETagDotNet (string filename, bool analyze)
|
public APETagDotNet (string filename, bool analyze, bool isReadonly)
|
||||||
{
|
{
|
||||||
m_spIO = new FileStream (filename, FileMode.Open, FileAccess.Read, FileShare.Read);
|
m_spIO = new FileStream(filename, FileMode.Open, isReadonly?FileAccess.Read:FileAccess.ReadWrite, FileShare.Read);
|
||||||
m_bAnalyzed = false;
|
m_bAnalyzed = false;
|
||||||
m_aryFields = new APETagField[0];
|
m_aryFields = new APETagField[0];
|
||||||
m_nTagBytes = 0;
|
m_nTagBytes = 0;
|
||||||
@@ -183,16 +183,23 @@ namespace APETagsDotNet
|
|||||||
if (analyze) Analyze ();
|
if (analyze) Analyze ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Close ()
|
||||||
|
{
|
||||||
|
m_spIO.Close ();
|
||||||
|
ClearFields ();
|
||||||
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
~APETagDotNet () { ClearFields (); }
|
~APETagDotNet () { }
|
||||||
|
|
||||||
// save the tag to the I/O source (bUseOldID3 forces it to save as an ID3v1.1 tag instead of an APE tag)
|
// save the tag to the I/O source (bUseOldID3 forces it to save as an ID3v1.1 tag instead of an APE tag)
|
||||||
int Save ()
|
public bool Save ()
|
||||||
{
|
{
|
||||||
if (!Remove(false))
|
if (!Remove(false))
|
||||||
return -1;
|
return false;
|
||||||
|
|
||||||
if (m_aryFields.Length == 0) { return 0; }
|
if (m_aryFields.Length == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
int z = 0;
|
int z = 0;
|
||||||
|
|
||||||
@@ -221,7 +228,7 @@ namespace APETagsDotNet
|
|||||||
|
|
||||||
// dump the tag to the I/O source
|
// dump the tag to the I/O source
|
||||||
WriteBufferToEndOfIO (spRawTag);
|
WriteBufferToEndOfIO (spRawTag);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes any tags from the file (bUpdate determines whether is should re-analyze after removing the tag)
|
// removes any tags from the file (bUpdate determines whether is should re-analyze after removing the tag)
|
||||||
@@ -294,7 +301,7 @@ namespace APETagsDotNet
|
|||||||
|
|
||||||
// sets the value of a field (use nFieldBytes = -1 for null terminated strings)
|
// sets the value of a field (use nFieldBytes = -1 for null terminated strings)
|
||||||
// note: using NULL or "" for a string type will remove the field
|
// note: using NULL or "" for a string type will remove the field
|
||||||
void SetFieldString(string fieldName, string fieldValue)
|
public void SetFieldString(string fieldName, string fieldValue)
|
||||||
{
|
{
|
||||||
// remove if empty
|
// remove if empty
|
||||||
if (fieldValue == "")
|
if (fieldValue == "")
|
||||||
@@ -390,6 +397,22 @@ namespace APETagsDotNet
|
|||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetStringTags(NameValueCollection tags, bool mapFromFlac)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < tags.Count; i++)
|
||||||
|
{
|
||||||
|
String [] tagValues = tags.GetValues(i);
|
||||||
|
String tagName = tags.GetKey (i);
|
||||||
|
if (mapFromFlac)
|
||||||
|
{
|
||||||
|
if (tagName.ToUpper() == "DATE")
|
||||||
|
tagName = "YEAR";
|
||||||
|
if (tagName.ToUpper() == "TRACKNUMBER")
|
||||||
|
tagName = "TRACK";
|
||||||
|
}
|
||||||
|
SetFieldString(tagName, tagValues[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// remove a specific field
|
// remove a specific field
|
||||||
void RemoveField(string pFieldName)
|
void RemoveField(string pFieldName)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace JDP {
|
|||||||
|
|
||||||
public interface IAudioDest {
|
public interface IAudioDest {
|
||||||
void Write(byte[] buff, uint sampleCount);
|
void Write(byte[] buff, uint sampleCount);
|
||||||
|
bool SetTags(NameValueCollection tags);
|
||||||
void Close();
|
void Close();
|
||||||
long FinalSampleCount { set; }
|
long FinalSampleCount { set; }
|
||||||
}
|
}
|
||||||
@@ -65,6 +66,10 @@ namespace JDP {
|
|||||||
public DummyWriter (string path, int bitsPerSample, int channelCount, int sampleRate) {
|
public DummyWriter (string path, int bitsPerSample, int channelCount, int sampleRate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SetTags(NameValueCollection tags)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void Close() {
|
public void Close() {
|
||||||
}
|
}
|
||||||
@@ -292,6 +297,11 @@ namespace JDP {
|
|||||||
WriteHeaders();
|
WriteHeaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SetTags(NameValueCollection tags)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void WriteHeaders() {
|
private void WriteHeaders() {
|
||||||
const uint fccRIFF = 0x46464952;
|
const uint fccRIFF = 0x46464952;
|
||||||
const uint fccWAVE = 0x45564157;
|
const uint fccWAVE = 0x45564157;
|
||||||
@@ -535,9 +545,10 @@ namespace JDP {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTags(NameValueCollection tags)
|
public bool SetTags(NameValueCollection tags)
|
||||||
{
|
{
|
||||||
_flacWriter.SetTags (tags);
|
_flacWriter.SetTags (tags);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close() {
|
public void Close() {
|
||||||
@@ -809,6 +820,12 @@ namespace JDP {
|
|||||||
_wavPackWriter = new WavPackDotNet.WavPackWriter(path, bitsPerSample, channelCount, sampleRate);
|
_wavPackWriter = new WavPackDotNet.WavPackWriter(path, bitsPerSample, channelCount, sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SetTags(NameValueCollection tags)
|
||||||
|
{
|
||||||
|
_wavPackWriter.SetTags(tags);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public long FinalSampleCount {
|
public long FinalSampleCount {
|
||||||
get {
|
get {
|
||||||
return _wavPackWriter.FinalSampleCount;
|
return _wavPackWriter.FinalSampleCount;
|
||||||
|
|||||||
@@ -945,7 +945,7 @@ namespace JDP {
|
|||||||
uint timeRelativeToFileStart = 0;
|
uint timeRelativeToFileStart = 0;
|
||||||
|
|
||||||
using (sw) {
|
using (sw) {
|
||||||
if (_accurateRipId != null)
|
if (_accurateRipId != null && _config.writeArTags)
|
||||||
WriteLine(sw, 0, "REM ACCURATERIPID " +
|
WriteLine(sw, 0, "REM ACCURATERIPID " +
|
||||||
_accurateRipId);
|
_accurateRipId);
|
||||||
|
|
||||||
@@ -1602,9 +1602,8 @@ namespace JDP {
|
|||||||
{
|
{
|
||||||
iDest++;
|
iDest++;
|
||||||
audioDest = GetAudioDest(destPaths[iDest], destLengths[iDest], noOutput);
|
audioDest = GetAudioDest(destPaths[iDest], destLengths[iDest], noOutput);
|
||||||
if (audioDest is FLACWriter)
|
if (audioDest is FLACWriter || audioDest is WavPackWriter)
|
||||||
{
|
{
|
||||||
FLACWriter w = (FLACWriter)audioDest;
|
|
||||||
NameValueCollection destTags = new NameValueCollection();
|
NameValueCollection destTags = new NameValueCollection();
|
||||||
|
|
||||||
if (_hasEmbeddedCUESheet || _hasSingleFilename)
|
if (_hasEmbeddedCUESheet || _hasSingleFilename)
|
||||||
@@ -1649,7 +1648,7 @@ namespace JDP {
|
|||||||
else
|
else
|
||||||
destTags.Add("ACCURATERIPID", _accurateRipId);
|
destTags.Add("ACCURATERIPID", _accurateRipId);
|
||||||
}
|
}
|
||||||
w.SetTags(destTags);
|
audioDest.SetTags(destTags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -803,8 +803,8 @@ namespace JDP {
|
|||||||
|
|
||||||
private void updateOutputStyles()
|
private void updateOutputStyles()
|
||||||
{
|
{
|
||||||
rbEmbedCUE.Enabled = rbFLAC.Checked;
|
rbEmbedCUE.Enabled = rbFLAC.Checked || rbWavPack.Checked;
|
||||||
rbNoAudio.Enabled = rbWAV.Enabled = rbWavPack.Enabled = !rbEmbedCUE.Checked;
|
rbNoAudio.Enabled = rbWAV.Enabled = !rbEmbedCUE.Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rbWAV_CheckedChanged(object sender, EventArgs e)
|
private void rbWAV_CheckedChanged(object sender, EventArgs e)
|
||||||
|
|||||||
@@ -116,7 +116,12 @@ namespace WavPackDotNet {
|
|||||||
|
|
||||||
property NameValueCollection^ Tags {
|
property NameValueCollection^ Tags {
|
||||||
NameValueCollection^ get () {
|
NameValueCollection^ get () {
|
||||||
if (!_tags) _tags = (gcnew APETagDotNet (_path, true))->GetStringTags (true);
|
if (!_tags)
|
||||||
|
{
|
||||||
|
APETagDotNet^ apeTag = gcnew APETagDotNet (_path, true, true);
|
||||||
|
_tags = apeTag->GetStringTags (true);
|
||||||
|
apeTag->Close ();
|
||||||
|
}
|
||||||
return _tags;
|
return _tags;
|
||||||
}
|
}
|
||||||
void set (NameValueCollection ^tags) {
|
void set (NameValueCollection ^tags) {
|
||||||
@@ -157,6 +162,9 @@ namespace WavPackDotNet {
|
|||||||
throw gcnew Exception("Only stereo and mono audio formats are allowed.");
|
throw gcnew Exception("Only stereo and mono audio formats are allowed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_path = path;
|
||||||
|
_tags = gcnew NameValueCollection();
|
||||||
|
|
||||||
_compressionMode = 1;
|
_compressionMode = 1;
|
||||||
_extraMode = 0;
|
_extraMode = 0;
|
||||||
|
|
||||||
@@ -180,6 +188,15 @@ namespace WavPackDotNet {
|
|||||||
if ((_finalSampleCount != 0) && (_samplesWritten != _finalSampleCount)) {
|
if ((_finalSampleCount != 0) && (_samplesWritten != _finalSampleCount)) {
|
||||||
throw gcnew Exception("Samples written differs from the expected sample count.");
|
throw gcnew Exception("Samples written differs from the expected sample count.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_tags->Count > 0)
|
||||||
|
{
|
||||||
|
APETagDotNet^ apeTag = gcnew APETagDotNet (_path, true, false);
|
||||||
|
apeTag->SetStringTags (_tags, true);
|
||||||
|
apeTag->Save();
|
||||||
|
apeTag->Close();
|
||||||
|
_tags->Clear ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property Int32 FinalSampleCount {
|
property Int32 FinalSampleCount {
|
||||||
@@ -233,6 +250,10 @@ namespace WavPackDotNet {
|
|||||||
_samplesWritten += sampleCount;
|
_samplesWritten += sampleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetTags (NameValueCollection^ tags) {
|
||||||
|
_tags = tags;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FILE *_hFile;
|
FILE *_hFile;
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
@@ -240,6 +261,8 @@ namespace WavPackDotNet {
|
|||||||
Int32 _finalSampleCount, _samplesWritten;
|
Int32 _finalSampleCount, _samplesWritten;
|
||||||
Int32 _bitsPerSample, _channelCount, _sampleRate;
|
Int32 _bitsPerSample, _channelCount, _sampleRate;
|
||||||
Int32 _compressionMode, _extraMode;
|
Int32 _compressionMode, _extraMode;
|
||||||
|
NameValueCollection^ _tags;
|
||||||
|
String^ _path;
|
||||||
|
|
||||||
void Initialize() {
|
void Initialize() {
|
||||||
WavpackConfig config;
|
WavpackConfig config;
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user