Initial commit — M3U playlist tool with MP3/AAC encoding
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,58 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
//
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
[assembly: AssemblyTitle("")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||
//
|
||||
// Use the attributes below to control which key is used for signing.
|
||||
//
|
||||
// Notes:
|
||||
// (*) If no key is specified, the assembly is not signed.
|
||||
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||
// a key.
|
||||
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||
// following processing occurs:
|
||||
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||
// in the KeyFile is installed into the CSP and used.
|
||||
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||
// When specifying the KeyFile, the location of the KeyFile should be
|
||||
// relative to the project output directory which is
|
||||
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||
// located in the project directory, you would specify the AssemblyKeyFile
|
||||
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||
// documentation for more information on this.
|
||||
//
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyKeyFile("")]
|
||||
[assembly: AssemblyKeyName("")]
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
public class DoNothingProgressCallback : IProgressCallback
|
||||
{
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to initialize
|
||||
/// the progress callback.
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum.</param>
|
||||
/// <param name="maximum">The maximum.</param>
|
||||
public void Begin(int minimum, int maximum)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to initialize
|
||||
/// the progress callback, without setting the range
|
||||
/// </summary>
|
||||
public void Begin()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to reset the range in the
|
||||
/// progress callback
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum.</param>
|
||||
/// <param name="maximum">The maximum.</param>
|
||||
public void SetRange(int minimum, int maximum)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to update the progress text.
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
public void SetText(string text)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
public void StepTo(int val)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to step the progress meter to a
|
||||
/// particular value.
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
public void Increment(int val)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this property is true, then you should abort work
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is aborting; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsAborting
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to finalize the progress meter
|
||||
/// </summary>
|
||||
public void End()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// This defines an interface which can be implemented by UI elements
|
||||
/// which indicate the progress of a long operation.
|
||||
/// (See ProgressWindow for a typical implementation)
|
||||
/// </summary>
|
||||
/// <remarks>Based on http://www.codeproject.com/cs/miscctrl/progressdialog.asp </remarks>
|
||||
public interface IProgressCallback
|
||||
{
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to initialize
|
||||
/// the progress callback.
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum.</param>
|
||||
/// <param name="maximum">The maximum.</param>
|
||||
void Begin(int minimum, int maximum);
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to initialize
|
||||
/// the progress callback, without setting the range
|
||||
/// </summary>
|
||||
void Begin();
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to reset the range in the
|
||||
/// progress callback
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum.</param>
|
||||
/// <param name="maximum">The maximum.</param>
|
||||
void SetRange(int minimum, int maximum);
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to update the progress text.
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
void SetText(String text);
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
void StepTo(int val);
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to step the progress meter to a
|
||||
/// particular value.
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
void Increment(int val);
|
||||
|
||||
/// <summary>
|
||||
/// If this property is true, then you should abort work
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is aborting; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsAborting
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to finalize the progress meter
|
||||
/// </summary>
|
||||
void End();
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
Copyright (c) 2005, Marc Clifton
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of MyXaml nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Clifton.Collections.Generic
|
||||
{
|
||||
[Serializable]
|
||||
public class KeyedList<K, V> : IDictionary<K, V>, IList<KeyValuePair<K, V>>
|
||||
{
|
||||
private Dictionary<K, V> objectTable = new Dictionary<K, V>();
|
||||
private List<KeyValuePair<K, V>> objectList = new List<KeyValuePair<K, V>>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns false.
|
||||
/// </summary>
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of entries in the KeyedList.
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return objectList.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the value at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="idx">The index.</param>
|
||||
/// <returns>The value.</returns>
|
||||
public KeyValuePair<K, V> this[int idx]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (idx < 0 || idx >= Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
|
||||
return objectList[idx];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (idx < 0 || idx >= Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
|
||||
objectList[idx] = value;
|
||||
objectTable[value.Key] = value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the value associated with the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns>The associated value.</returns>
|
||||
public virtual V this[K key]
|
||||
{
|
||||
get { return objectTable[key]; }
|
||||
set
|
||||
{
|
||||
if (objectTable.ContainsKey(key))
|
||||
{
|
||||
objectTable[key] = value;
|
||||
objectList[IndexOf(key)] = new KeyValuePair<K, V>(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an unordered list of keys.
|
||||
/// This collection refers back to the keys in the original Dictionary.
|
||||
/// </summary>
|
||||
public ICollection<K> Keys
|
||||
{
|
||||
get { return objectTable.Keys; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an unordered list of values.
|
||||
/// This collection refers back to the values in the original Dictionary.
|
||||
/// </summary>
|
||||
public ICollection<V> Values
|
||||
{
|
||||
get { return objectTable.Values; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the ordered list of keys.
|
||||
/// This is a copy of the keys in the original Dictionary.
|
||||
/// </summary>
|
||||
public List<K> OrderedKeys
|
||||
{
|
||||
get
|
||||
{
|
||||
List<K> retList = new List<K>();
|
||||
|
||||
foreach (KeyValuePair<K, V> kvp in objectList)
|
||||
{
|
||||
retList.Add(kvp.Key);
|
||||
}
|
||||
|
||||
return retList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the ordered list of values.
|
||||
/// This is a copy of the values in the original Dictionary.
|
||||
/// </summary>
|
||||
public List<V> OrderedValues
|
||||
{
|
||||
get
|
||||
{
|
||||
List<V> retList = new List<V>();
|
||||
|
||||
foreach (KeyValuePair<K, V> kvp in objectList)
|
||||
{
|
||||
retList.Add(kvp.Value);
|
||||
}
|
||||
|
||||
return retList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the key at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="idx">The index.</param>
|
||||
/// <returns>The key at the index.</returns>
|
||||
public K GetKey(int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
|
||||
return objectList[idx].Key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="idx">The index.</param>
|
||||
/// <returns>The value at the index.</returns>
|
||||
public V GetValue(int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
|
||||
return objectList[idx].Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the index of a particular key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to find the index of.</param>
|
||||
/// <returns>The index of the key, or -1 if not found.</returns>
|
||||
public int IndexOf(K key)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
for (int i = 0; i < objectList.Count; i++)
|
||||
{
|
||||
if (objectList[i].Key.Equals(key))
|
||||
{
|
||||
ret = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given the key-value pair, find the index.
|
||||
/// </summary>
|
||||
/// <param name="kvp">The key-value pair.</param>
|
||||
/// <returns>The index, or -1 if not found.</returns>
|
||||
public int IndexOf(KeyValuePair<K, V> kvp)
|
||||
{
|
||||
return IndexOf(kvp.Key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Dictionary class backing the KeyedList.
|
||||
/// </summary>
|
||||
public Dictionary<K, V> ObjectTable
|
||||
{
|
||||
get { return objectTable; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all entries in the KeyedList.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
objectTable.Clear();
|
||||
objectList.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if the KeyedList contains the key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns>True if the key is found.</returns>
|
||||
public bool ContainsKey(K key)
|
||||
{
|
||||
return objectTable.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if the KeyedList contains the key in the key-value pair.
|
||||
/// </summary>
|
||||
/// <param name="kvp">The key-value pair.</param>
|
||||
/// <returns>True if the key is found.</returns>
|
||||
public bool Contains(KeyValuePair<K, V> kvp)
|
||||
{
|
||||
return objectTable.ContainsKey(kvp.Key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a key-value pair to the KeyedList.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="value">The associated value.</param>
|
||||
public void Add(K key, V value)
|
||||
{
|
||||
objectTable.Add(key, value);
|
||||
objectList.Add(new KeyValuePair<K, V>(key, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a key-value pair to the KeyedList.
|
||||
/// </summary>
|
||||
/// <param name="kvp">The KeyValuePair instance.</param>
|
||||
public void Add(KeyValuePair<K, V> kvp)
|
||||
{
|
||||
Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the entire key-value pairs to the KeyValuePair array, starting
|
||||
/// at the specified index of the target array. The array is populated
|
||||
/// as an ordered list.
|
||||
/// </summary>
|
||||
/// <param name="kvpa">The KeyValuePair array.</param>
|
||||
/// <param name="idx">The position to start the copy.</param>
|
||||
public void CopyTo(KeyValuePair<K, V>[] kvpa, int idx)
|
||||
{
|
||||
objectList.CopyTo(kvpa, idx);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert the key-value at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="idx">The zero-based insert point.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public void Insert(int idx, K key, V value)
|
||||
{
|
||||
if ((idx < 0) || (idx > Count))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
|
||||
objectTable.Add(key, value);
|
||||
objectList.Insert(idx, new KeyValuePair<K, V>(key, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert the key-value pair at the specified index location.
|
||||
/// </summary>
|
||||
/// <param name="idx">The key.</param>
|
||||
/// <param name="kvp">The value.</param>
|
||||
public void Insert(int idx, KeyValuePair<K, V> kvp)
|
||||
{
|
||||
if ((idx < 0) || (idx > Count))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
|
||||
objectTable.Add(kvp.Key, kvp.Value);
|
||||
objectList.Insert(idx, kvp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the entry.
|
||||
/// </summary>
|
||||
/// <param name="key">The key identifying the key-value pair.</param>
|
||||
/// <returns>True if removed.</returns>
|
||||
public bool Remove(K key)
|
||||
{
|
||||
bool found = objectTable.Remove(key);
|
||||
|
||||
if (found)
|
||||
{
|
||||
objectList.RemoveAt(IndexOf(key));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the key in the specified KeyValuePair instance. The Value
|
||||
/// property is ignored.
|
||||
/// </summary>
|
||||
/// <param name="kvp">The key-value identifying the entry.</param>
|
||||
/// <returns>True if removed.</returns>
|
||||
public bool Remove(KeyValuePair<K, V> kvp)
|
||||
{
|
||||
return Remove(kvp.Key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the entry at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="idx">The index to the entry to be removed.</param>
|
||||
public void RemoveAt(int idx)
|
||||
{
|
||||
if ((idx < 0) || (idx >= Count))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
|
||||
objectTable.Remove(objectList[idx].Key);
|
||||
objectList.RemoveAt(idx);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to get the value, given the key, without throwing an exception if not found.
|
||||
/// </summary>
|
||||
/// <param name="key">The key indentifying the entry.</param>
|
||||
/// <param name="val">The value, if found.</param>
|
||||
/// <returns>True if found.</returns>
|
||||
public bool TryGetValue(K key, out V val)
|
||||
{
|
||||
return objectTable.TryGetValue(key, out val);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an ordered System.Collections KeyValuePair objects.
|
||||
/// </summary>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return objectList.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an ordered KeyValuePair enumerator.
|
||||
/// </summary>
|
||||
IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator()
|
||||
{
|
||||
return objectList.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
public class LongestCommonSubstrings
|
||||
{
|
||||
//def longest_common_substrings(S, T):
|
||||
// maks = 0 # length of longest match
|
||||
// ret = Set([""]) # the longest matches we have found
|
||||
// last = {} # length of matches ending at S[i-1] and
|
||||
// next = {} # at S[i] for T[0]...T[n-1]
|
||||
// for i in xrange(len(S)):
|
||||
// for j in xrange(len(T)):
|
||||
// if S[i] == T[j]:
|
||||
// if j-1 in last:
|
||||
// next[j] = last[j-1] + 1
|
||||
// else:
|
||||
// next[j] = 1
|
||||
// if next[j] > maks:
|
||||
// maks = next[j]
|
||||
// ret = Set()
|
||||
// if next[j] == maks:
|
||||
// ret.add(S[i-maks+1:i+1]) # equals T[j-maks+1:j+1]
|
||||
// last = next
|
||||
// next = {}
|
||||
// return ret
|
||||
|
||||
public static List<string> GetLongestSubstring(string s, string t)
|
||||
{
|
||||
int maks = 0;
|
||||
List<string> ret = new List<string>();
|
||||
Dictionary<int, int> last = new Dictionary<int, int>();
|
||||
Dictionary<int, int> next = new Dictionary<int, int>();
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
for (int j = 0; j < t.Length; j++)
|
||||
{
|
||||
if (s[i] == t[j])
|
||||
{
|
||||
if (last.ContainsKey(j-1))
|
||||
next[j] = last[j - 1] + 1;
|
||||
else
|
||||
next[j] = 1;
|
||||
|
||||
if (next[j] > maks)
|
||||
{
|
||||
maks = next[j];
|
||||
ret.Clear();
|
||||
}
|
||||
if (next[j] == maks)
|
||||
ret.Add(s.Substring(i - maks + 1, maks));
|
||||
}
|
||||
}
|
||||
last = next;
|
||||
next = new Dictionary<int, int>();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public class LongestCommonSequence<T> where T : IEnumerable
|
||||
{
|
||||
public enum BackTracking {
|
||||
NEITHER,
|
||||
UP,
|
||||
LEFT,
|
||||
UP_AND_LEFT
|
||||
}
|
||||
|
||||
private static int ConsecutiveMeasure(int k)
|
||||
{
|
||||
//f(k)=k*a - b;
|
||||
return k*k;
|
||||
}
|
||||
|
||||
//public T DoLCS(T list1, T list2)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
private object[] LCS(object[] list1, object[] list2)
|
||||
{
|
||||
int m=list1.Length ;
|
||||
int n=list2.Length ;
|
||||
|
||||
int[,] lcs=new int[m+1, n+1];
|
||||
BackTracking[ , ] backTracer=new BackTracking[m+1, n+1];
|
||||
int[,] w=new int[m+1, n+1];
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i <= m; i++)
|
||||
{
|
||||
lcs[i,0] = 0;
|
||||
backTracer[i,0]=BackTracking.UP;
|
||||
|
||||
}
|
||||
for (j = 0; j <= n; j++)
|
||||
{
|
||||
lcs[0,j]=0;
|
||||
backTracer[0,j]=BackTracking.LEFT;
|
||||
}
|
||||
|
||||
for (i = 1; i <= m; i++)
|
||||
{
|
||||
for (j = 1; j <= n; j++)
|
||||
{
|
||||
if(list1[i-1] == list2[j-1])
|
||||
{
|
||||
int k = w[i-1, j-1];
|
||||
//lcs[i,j] = lcs[i-1,j-1] + 1;
|
||||
lcs[i,j]=lcs[i-1,j-1] + ConsecutiveMeasure(k+1) - ConsecutiveMeasure(k);
|
||||
backTracer[i,j] = BackTracking.UP_AND_LEFT;
|
||||
w[i,j] = k+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcs[i,j] = lcs[i-1,j-1];
|
||||
backTracer[i,j] = BackTracking.NEITHER;
|
||||
}
|
||||
|
||||
if(lcs[i-1,j] >= lcs[i,j])
|
||||
{
|
||||
lcs[i,j] = lcs[i-1,j];
|
||||
backTracer[i,j] = BackTracking.UP;
|
||||
w[i,j] = 0;
|
||||
}
|
||||
|
||||
if(lcs[i,j-1] >= lcs[i,j])
|
||||
{
|
||||
lcs[i,j] = lcs[i,j-1];
|
||||
backTracer [i,j] = BackTracking.LEFT;
|
||||
w[i,j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i=m;
|
||||
j=n;
|
||||
|
||||
Stack<object> subseq = new Stack<object>();
|
||||
// int p=lcs[i,j];
|
||||
|
||||
//trace the backtracking matrix.
|
||||
while( i > 0 || j > 0 )
|
||||
{
|
||||
if( backTracer[i,j] == BackTracking.UP_AND_LEFT )
|
||||
{
|
||||
i--;
|
||||
j--;
|
||||
subseq.Push(list1[i]);
|
||||
// subseq = list1[i] + subseq;
|
||||
Trace.WriteLine(i + " " + list1[i] + " " + j) ;
|
||||
}
|
||||
|
||||
else if( backTracer[i,j] == BackTracking.UP )
|
||||
{
|
||||
i--;
|
||||
}
|
||||
|
||||
else if( backTracer[i,j] == BackTracking.LEFT )
|
||||
{
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return subseq.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for m3uFromDirectory.
|
||||
/// </summary>
|
||||
public class M3uCreate
|
||||
{
|
||||
/// <summary>
|
||||
/// Use the parent's directory name for the m3u name
|
||||
/// </summary>
|
||||
private bool mUseGeneratedOuputFilename = true;
|
||||
|
||||
/// <summary>
|
||||
/// Directory to grab the files from
|
||||
/// </summary>
|
||||
private DirectoryInfo mInputDir;
|
||||
|
||||
/// <summary>
|
||||
/// Ouput m3u filename, if it isn't generated
|
||||
/// </summary>
|
||||
private string mOutputFilename = null;
|
||||
|
||||
/// <summary>
|
||||
/// Filter for input filenames
|
||||
/// </summary>
|
||||
private string mFileFilter = "*.mp3";
|
||||
|
||||
public bool UseGeneratedOuputFilename
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUseGeneratedOuputFilename;
|
||||
}
|
||||
set
|
||||
{
|
||||
mUseGeneratedOuputFilename = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string OutputFilename
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mUseGeneratedOuputFilename)
|
||||
{
|
||||
Debug.WriteLine("OutputFilename:" + mInputDir.FullName + "\\" + mInputDir.Name + ".m3u");
|
||||
return mInputDir.FullName + "\\" + mInputDir.Name + ".m3u";
|
||||
}
|
||||
return mOutputFilename;
|
||||
}
|
||||
set
|
||||
{
|
||||
mOutputFilename = value;
|
||||
mUseGeneratedOuputFilename = false;
|
||||
}
|
||||
}
|
||||
|
||||
public M3uCreate(string dir) : this (new DirectoryInfo(dir))
|
||||
{
|
||||
}
|
||||
|
||||
public M3uCreate(DirectoryInfo inputDir)
|
||||
{
|
||||
mInputDir = inputDir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// dir: "\foo\bar\" file: "\foo\bar\myfile" output: ""
|
||||
/// dir: "\foo\" file: "\foo\bar\myfile" output: ".."
|
||||
/// dir: "\" file: "\foo\bar\myfile" output: "..\.."
|
||||
/// dir: "\har" file: "\foo\bar\myfile" output: "..\..\har"
|
||||
/// dir: "\foo\bar\hey\" file: "\foo\bar\myfile" output: "hey\"
|
||||
/// </remarks>
|
||||
/// <param name="dir"></param>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
private string GetPath(DirectoryInfo dir, FileInfo file)
|
||||
{
|
||||
string source = dir.FullName;
|
||||
string target = file.Directory.FullName;
|
||||
|
||||
return GetPath(source, target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path.
|
||||
/// </summary>
|
||||
/// <param name="source">The source.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns></returns>
|
||||
private string GetPath(string source, string target)
|
||||
{
|
||||
int lastCommonIndex = GetLastCommonIndex(source, target);
|
||||
Debug.WriteLine(String.Format("s:{0} , t:{1} lastCommon:{2} ", source, target, lastCommonIndex));
|
||||
|
||||
int slashCount = CountCharacters(source, lastCommonIndex + 1, '\\');
|
||||
|
||||
string path = "";
|
||||
for (int i = 0; i < slashCount; i++)
|
||||
{
|
||||
path += "..\\";
|
||||
}
|
||||
path += target.Substring(lastCommonIndex);
|
||||
if (path.Length > 0 && path[path.Length - 1] != '\\')
|
||||
path += "\\";
|
||||
Debug.WriteLine(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
private int CountCharacters(string str, int startIdx, char c)
|
||||
{
|
||||
int charsCount = 0;
|
||||
int currIdx = startIdx;
|
||||
while (currIdx < str.Length && (currIdx = str.IndexOf(c, currIdx) + 1) != 0)
|
||||
charsCount++;
|
||||
return charsCount;
|
||||
}
|
||||
|
||||
private int GetLastCommonIndex(string str1, string str2)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < str1.Length && i < str2.Length && Char.ToLower(str1[i]) == Char.ToLower(str2[i]))
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
public void Create()
|
||||
{
|
||||
string fileList = "";
|
||||
DirectoryInfo ouputDirectory = (new FileInfo(OutputFilename)).Directory;
|
||||
foreach (FileInfo info in mInputDir.GetFiles(mFileFilter))
|
||||
{
|
||||
string fileName = GetPath(ouputDirectory, info) + info.Name;
|
||||
Debug.WriteLine(fileName);
|
||||
fileList += fileName + Environment.NewLine;
|
||||
}
|
||||
SaveToFile(fileList, OutputFilename);
|
||||
}
|
||||
|
||||
private void SaveToFile(string contents, string outputFilename)
|
||||
{
|
||||
using (TextWriter tw = new StreamWriter(outputFilename))
|
||||
{
|
||||
tw.Write(contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for Form1.
|
||||
/// </summary>
|
||||
public class M3uMakeByDirectory : Form
|
||||
{
|
||||
private Button selectDirectoryButton;
|
||||
private TextBox m3uDirectoryTextBox;
|
||||
private TextBox outputTextBox;
|
||||
private Button m3uMakeButton;
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private Container components = null;
|
||||
|
||||
public M3uMakeByDirectory()
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
//
|
||||
// TODO: Add any constructor code after InitializeComponent call
|
||||
//
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.m3uDirectoryTextBox = new System.Windows.Forms.TextBox();
|
||||
this.outputTextBox = new System.Windows.Forms.TextBox();
|
||||
this.selectDirectoryButton = new System.Windows.Forms.Button();
|
||||
this.m3uMakeButton = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// m3uDirectoryTextBox
|
||||
//
|
||||
this.m3uDirectoryTextBox.Enabled = false;
|
||||
this.m3uDirectoryTextBox.Location = new System.Drawing.Point(8, 8);
|
||||
this.m3uDirectoryTextBox.Name = "m3uDirectoryTextBox";
|
||||
this.m3uDirectoryTextBox.Size = new System.Drawing.Size(176, 20);
|
||||
this.m3uDirectoryTextBox.TabIndex = 0;
|
||||
this.m3uDirectoryTextBox.Text = "";
|
||||
//
|
||||
// outputTextBox
|
||||
//
|
||||
this.outputTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.outputTextBox.Location = new System.Drawing.Point(8, 88);
|
||||
this.outputTextBox.Multiline = true;
|
||||
this.outputTextBox.Name = "outputTextBox";
|
||||
this.outputTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||
this.outputTextBox.Size = new System.Drawing.Size(272, 168);
|
||||
this.outputTextBox.TabIndex = 1;
|
||||
this.outputTextBox.Text = "";
|
||||
//
|
||||
// selectDirectoryButton
|
||||
//
|
||||
this.selectDirectoryButton.Location = new System.Drawing.Point(208, 8);
|
||||
this.selectDirectoryButton.Name = "selectDirectoryButton";
|
||||
this.selectDirectoryButton.TabIndex = 2;
|
||||
this.selectDirectoryButton.Text = "Select Dir...";
|
||||
this.selectDirectoryButton.Click += new System.EventHandler(this.selectDirectoryButton_Click);
|
||||
//
|
||||
// m3uMakeButton
|
||||
//
|
||||
this.m3uMakeButton.Enabled = false;
|
||||
this.m3uMakeButton.Location = new System.Drawing.Point(208, 40);
|
||||
this.m3uMakeButton.Name = "m3uMakeButton";
|
||||
this.m3uMakeButton.TabIndex = 3;
|
||||
this.m3uMakeButton.Text = "Make M3u";
|
||||
this.m3uMakeButton.Click += new System.EventHandler(this.m3uMakeButton_Click);
|
||||
//
|
||||
// MakeSubdir
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(292, 266);
|
||||
this.Controls.Add(this.m3uMakeButton);
|
||||
this.Controls.Add(this.selectDirectoryButton);
|
||||
this.Controls.Add(this.outputTextBox);
|
||||
this.Controls.Add(this.m3uDirectoryTextBox);
|
||||
this.Name = "MakeSubdir";
|
||||
this.Text = "M3u Make";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.Run(new M3uMakeByDirectory());
|
||||
}
|
||||
|
||||
private void selectDirectoryButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderBrowserDialog fbd = new FolderBrowserDialog();
|
||||
DialogResult dialogResult = fbd.ShowDialog(this);
|
||||
|
||||
if (dialogResult == DialogResult.OK)
|
||||
{
|
||||
m3uDirectoryTextBox.Text = fbd.SelectedPath;
|
||||
}
|
||||
UpdateRunButton();
|
||||
|
||||
}
|
||||
|
||||
private void UpdateRunButton()
|
||||
{
|
||||
if (m3uDirectoryTextBox.Text != null && m3uDirectoryTextBox.Text!="" && Directory.Exists(m3uDirectoryTextBox.Text))
|
||||
{
|
||||
m3uMakeButton.Enabled = true;
|
||||
}
|
||||
else
|
||||
m3uMakeButton.Enabled = false;
|
||||
}
|
||||
|
||||
private void CreateM3uThread()
|
||||
{
|
||||
CreateM3uRecursive(new DirectoryInfo(m3uDirectoryTextBox.Text));
|
||||
}
|
||||
|
||||
private void CreateM3uRecursive(DirectoryInfo info)
|
||||
{
|
||||
M3uCreate cm3u = new M3uCreate(info);
|
||||
cm3u.Create();
|
||||
outputTextBox.AppendText("Created " + cm3u.OutputFilename + Environment.NewLine);
|
||||
foreach (DirectoryInfo subDir in info.GetDirectories())
|
||||
{
|
||||
CreateM3uRecursive(subDir);
|
||||
}
|
||||
}
|
||||
|
||||
private void m3uMakeButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Thread t = new Thread(new ThreadStart(CreateM3uThread));
|
||||
t.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used forserialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="m3uDirectoryTextBox.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="m3uDirectoryTextBox.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="m3uDirectoryTextBox.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="outputTextBox.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="outputTextBox.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="outputTextBox.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="selectDirectoryButton.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="selectDirectoryButton.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="selectDirectoryButton.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="m3uMakeButton.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="m3uMakeButton.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="m3uMakeButton.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Name">
|
||||
<value>MakeSubdir</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
</root>
|
||||
Generated
+46
@@ -0,0 +1,46 @@
|
||||
namespace m3uTool
|
||||
{
|
||||
partial class M3uToAac
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// M3uToAac
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(434, 138);
|
||||
this.Name = "M3uToAac";
|
||||
this.Text = "M3uToAac";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
public partial class M3uToAac : Form
|
||||
{
|
||||
public class Mp3ToAacConversionOptions
|
||||
{
|
||||
string[] mInputFilenames;
|
||||
string[] mOutputFilenames;
|
||||
|
||||
|
||||
}
|
||||
public M3uToAac()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
public class Mp3Encoder : ProcessStreamWrapper
|
||||
{
|
||||
public Mp3Encoder(Mp3EncodingOptions encOpt)
|
||||
: base(encOpt)
|
||||
{
|
||||
}
|
||||
|
||||
public Mp3Encoder(Mp3EncodingOptions encOpt, Stream outputStream)
|
||||
: base(encOpt, outputStream)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string ProcessExecutableFilename
|
||||
{
|
||||
get { return @"c:\console\audio\lame.exe"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
/// <summary>
|
||||
/// LAME 32bits version 3.97 (beta 1, Oct 16 2005) (http://www.mp3dev.org/)
|
||||
///
|
||||
/// usage: lame [options] <infile> [outfile]
|
||||
///
|
||||
/// <infile> and/or <outfile> can be "-", which means stdin/stdout.
|
||||
///
|
||||
/// RECOMMENDED:
|
||||
/// lame -V2 input.wav output.mp3
|
||||
///
|
||||
/// OPTIONS:
|
||||
/// Input options:
|
||||
/// -r input is raw pcm
|
||||
/// -x force byte-swapping of input
|
||||
/// -s sfreq sampling frequency of input file (kHz) - default 44.1 kHz
|
||||
/// --bitwidth w input bit width is w (default 16)
|
||||
/// --scale <arg> scale input (multiply PCM data) by <arg>
|
||||
/// --scale-l <arg> scale channel 0 (left) input (multiply PCM data) by <arg>
|
||||
/// --scale-r <arg> scale channel 1 (right) input (multiply PCM data) by <arg>
|
||||
/// --mp1input input file is a MPEG Layer I file
|
||||
/// --mp2input input file is a MPEG Layer II file
|
||||
/// --mp3input input file is a MPEG Layer III file
|
||||
/// --nogap <file1> <file2> <...>
|
||||
/// gapless encoding for a set of contiguous files
|
||||
/// --nogapout <dir>
|
||||
/// output dir for gapless encoding (must precede --nogap)
|
||||
/// --nogaptags allow the use of VBR tags in gapless encoding
|
||||
///
|
||||
/// Operational options:
|
||||
/// -a downmix from stereo to mono file for mono encoding
|
||||
/// -m <mode> (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono
|
||||
/// default is (j) or (s) depending on bitrate
|
||||
/// joint = joins the best possible of MS and LR stereo
|
||||
/// simple = force LR stereo on all frames
|
||||
/// force = force MS stereo on all frames.
|
||||
/// --preset type type must be "medium", "standard", "extreme", "insane",
|
||||
/// or a value for an average desired bitrate and depending
|
||||
/// on the value specified, appropriate quality settings will
|
||||
/// be used.
|
||||
/// "--preset help" gives more info on these
|
||||
/// --comp <arg> choose bitrate to achive a compression ratio of <arg>
|
||||
/// --replaygain-fast compute RG fast but slightly inaccurately (default)
|
||||
/// --replaygain-accurate compute RG more accurately and find the peak sample
|
||||
/// --noreplaygain disable ReplayGain analysis
|
||||
/// --clipdetect enable --replaygain-accurate and print a message whether
|
||||
/// clipping occurs and how far the waveform is from full scale
|
||||
/// --freeformat produce a free format bitstream
|
||||
/// --decode input=mp3 file, output=wav
|
||||
/// -t disable writing wav header when using --decode
|
||||
///
|
||||
///
|
||||
/// Verbosity:
|
||||
/// --disptime <arg>print progress report every arg seconds
|
||||
/// -S don't print progress report, VBR histograms
|
||||
/// --nohist disable VBR histogram display
|
||||
/// --silent don't print anything on screen
|
||||
/// --quiet don't print anything on screen
|
||||
/// --brief print more useful information
|
||||
/// --verbose print a lot of useful information
|
||||
///
|
||||
/// Noise shaping & psycho acoustic algorithms:
|
||||
/// -q <arg> <arg> = 0...9. Default -q 5
|
||||
/// -q 0: Highest quality, very slow
|
||||
/// -q 9: Poor quality, but fast
|
||||
/// -h Same as -q 2. Recommended.
|
||||
/// -f Same as -q 7. Fast, ok quality
|
||||
///
|
||||
///
|
||||
/// CBR (constant bitrate, the default) options:
|
||||
/// -b <bitrate> set the bitrate in kbps, default 128 kbps
|
||||
/// --cbr enforce use of constant bitrate
|
||||
///
|
||||
/// ABR options:
|
||||
/// --abr <bitrate> specify average bitrate desired (instead of quality)
|
||||
///
|
||||
/// VBR options:
|
||||
/// -v use variable bitrate (VBR) (--vbr-old)
|
||||
/// --vbr-old use old variable bitrate (VBR) routine
|
||||
/// --vbr-new use new variable bitrate (VBR) routine
|
||||
/// -V n quality setting for VBR. default n=4
|
||||
/// 0=high quality,bigger files. 9=smaller files
|
||||
/// -b <bitrate> specify minimum allowed bitrate, default 32 kbps
|
||||
/// -B <bitrate> specify maximum allowed bitrate, default 320 kbps
|
||||
/// -F strictly enforce the -b option, for use with players that
|
||||
/// do not support low bitrate mp3
|
||||
/// -t disable writing LAME Tag
|
||||
/// -T enable and force writing LAME Tag
|
||||
///
|
||||
///
|
||||
/// PSY related:
|
||||
/// --short use short blocks when appropriate
|
||||
/// --noshort do not use short blocks
|
||||
/// --allshort use only short blocks
|
||||
/// --notemp disable temporal masking effect
|
||||
/// --nssafejoint M/S switching criterion
|
||||
/// --nsmsfix <arg> M/S switching tuning [effective 0-3.5]
|
||||
/// --interch x adjust inter-channel masking ratio
|
||||
/// --ns-bass x adjust masking for sfbs 0 - 6 (long) 0 - 5 (short)
|
||||
/// --ns-alto x adjust masking for sfbs 7 - 13 (long) 6 - 10 (short)
|
||||
/// --ns-treble x adjust masking for sfbs 14 - 21 (long) 11 - 12 (short)
|
||||
/// --ns-sfb21 x change ns-treble by x dB for sfb21
|
||||
///
|
||||
///
|
||||
/// experimental switches:
|
||||
/// -X n[,m] selects between different noise measurements
|
||||
/// n for long block, m for short. if m is omitted, m = n
|
||||
/// -Y lets LAME ignore noise in sfb21, like in CBR
|
||||
/// -Z [n] currently no effects
|
||||
///
|
||||
///
|
||||
/// MP3 header/stream options:
|
||||
/// -e <emp> de-emphasis n/5/c (obsolete)
|
||||
/// -c mark as copyright
|
||||
/// -o mark as non-original
|
||||
/// -p error protection. adds 16 bit checksum to every frame
|
||||
/// (the checksum is computed correctly)
|
||||
/// --nores disable the bit reservoir
|
||||
/// --strictly-enforce-ISO comply as much as possible to ISO MPEG spec
|
||||
///
|
||||
/// Filter options:
|
||||
/// -k keep ALL frequencies (disables all filters),
|
||||
/// Can cause ringing and twinkling
|
||||
/// --lowpass <freq> frequency(kHz), lowpass filter cutoff above freq
|
||||
/// --lowpass-width <freq> frequency(kHz) - default 15% of lowpass freq
|
||||
/// --highpass <freq> frequency(kHz), highpass filter cutoff below freq
|
||||
/// --highpass-width <freq> frequency(kHz) - default 15% of highpass freq
|
||||
/// --resample <sfreq> sampling frequency of output file(kHz)- default=automatic
|
||||
///
|
||||
///
|
||||
/// ID3 tag options:
|
||||
/// --tt <title> audio/song title (max 30 chars for version 1 tag)
|
||||
/// --ta <artist> audio/song artist (max 30 chars for version 1 tag)
|
||||
/// --tl <album> audio/song album (max 30 chars for version 1 tag)
|
||||
/// --ty <year> audio/song year of issue (1 to 9999)
|
||||
/// --tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1)
|
||||
/// --tn <track> audio/song track number (1 to 255, creates v1.1 tag)
|
||||
/// --tg <genre> audio/song genre (name or number in list)
|
||||
/// --add-id3v2 force addition of version 2 tag
|
||||
/// --id3v1-only add only a version 1 tag
|
||||
/// --id3v2-only add only a version 2 tag
|
||||
/// --space-id3v1 pad version 1 tag with spaces instead of nulls
|
||||
/// --pad-id3v2 pad version 2 tag with extra 128 bytes
|
||||
/// --genre-list print alphabetically sorted ID3 genre list and exit
|
||||
/// --ignore-tag-errors ignore errors in values passed for tags
|
||||
///
|
||||
/// Note: A version 2 tag will NOT be added unless one of the input fields
|
||||
/// won't fit in a version 1 tag (e.g. the title string is longer than 30
|
||||
/// characters), or the '--add-id3v2' or '--id3v2-only' options are used,
|
||||
/// or output is redirected to stdout.
|
||||
///
|
||||
///
|
||||
/// MS-Windows-specific options:
|
||||
/// --priority <type> sets the process priority:
|
||||
/// 0,1 = Low priority (IDLE_PRIORITY_CLASS)
|
||||
/// 2 = normal priority (NORMAL_PRIORITY_CLASS, defau
|
||||
/// lt)
|
||||
/// 3,4 = High priority (HIGH_PRIORITY_CLASS))
|
||||
/// Note: Calling '--priority' without a parameter will select priority 0.
|
||||
///
|
||||
///
|
||||
/// Platform specific:
|
||||
/// --noasm <instructions> disable assembly optimizations for mmx/3dnow/sse
|
||||
///
|
||||
///
|
||||
///
|
||||
/// MPEG-1 layer III sample frequencies (kHz): 32 48 44.1
|
||||
/// bitrates (kbps): 32 40 48 56 64 80 96 112 128 160 192 224 256 320
|
||||
///
|
||||
/// MPEG-2 layer III sample frequencies (kHz): 16 24 22.05
|
||||
/// bitrates (kbps): 8 16 24 32 40 48 56 64 80 96 112 128 144 160
|
||||
///
|
||||
/// MPEG-2.5 layer III sample frequencies (kHz): 8 12 11.025
|
||||
/// bitrates (kbps): 8 16 24 32 40 48 56 64 80 96 112 128 144 160
|
||||
/// </summary>
|
||||
public class Mp3EncodingOptions : ProcessArguments
|
||||
{
|
||||
#region Private variables
|
||||
/// <summary>
|
||||
/// Input filename. Can be "-", which means stdin.
|
||||
/// </summary>
|
||||
private string mInfile = null;
|
||||
|
||||
/// <summary>
|
||||
/// Output filename. Can be "-", which means stdout.
|
||||
/// </summary>
|
||||
private string mOutfile = null;
|
||||
|
||||
/// <summary>
|
||||
/// input is raw pcm (-r)
|
||||
/// </summary>
|
||||
private bool mRawPCMInputMode = false;
|
||||
|
||||
/// <summary>
|
||||
/// force byte-swapping of input (-x)
|
||||
/// </summary>
|
||||
private bool mForceByteSwappingOfInput = false;
|
||||
|
||||
/// <summary>
|
||||
/// sampling frequency of input file (kHz) - default 44.1 kHz (-s sfreq)
|
||||
/// </summary>
|
||||
private SampleRateFrequency mRawPCMInputSampleSize = SampleRateFrequency.Hz_44100;
|
||||
|
||||
/// <summary>
|
||||
/// input bit width is w (default 16) (--bitwidth w)
|
||||
/// </summary>
|
||||
private int mRawPCMInputSampleRate = 16;
|
||||
|
||||
/// <summary>
|
||||
/// input file is a MPEG Layer III file (--mp3input)
|
||||
/// </summary>
|
||||
private bool mMp3Input = false;
|
||||
|
||||
/// <summary>
|
||||
/// downmix from stereo to mono file for mono encoding (-a)
|
||||
/// </summary>
|
||||
private bool mMonoDownmixing = false;
|
||||
|
||||
/// <summary>
|
||||
/// (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono (-m)
|
||||
/// </summary>
|
||||
private ChannelMode mChannelMode = ChannelMode.JointStereo;
|
||||
|
||||
/// <summary>
|
||||
/// produce a free format bitstream (--freeformat)
|
||||
/// </summary>
|
||||
private bool mFreeFormat = false;
|
||||
|
||||
/// <summary>
|
||||
/// input=mp3 file, output=wav (--decode)
|
||||
/// </summary>
|
||||
private bool mDecodeWav = false;
|
||||
|
||||
/// <summary>
|
||||
/// disable writing wav header when using --decode (-t)
|
||||
/// </summary>
|
||||
private bool mDisableWavHeader = false;
|
||||
|
||||
/// <summary>
|
||||
/// Set the bitrate in kbps, default 128 kbps -b <bitrate>
|
||||
/// </summary>
|
||||
private BitRate mBitRate = BitRate.KBPS_0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <summary>
|
||||
/// Input filename. Can be "-", which means stdin.
|
||||
/// </summary>
|
||||
public string Infile
|
||||
{
|
||||
get { return mInfile; }
|
||||
set { mInfile = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output filename. Can be "-", which means stdout.
|
||||
/// </summary>
|
||||
public string Outfile
|
||||
{
|
||||
get { return mOutfile; }
|
||||
set { mOutfile = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// input is raw pcm (-r)
|
||||
/// </summary>
|
||||
public bool RawPCMInputMode
|
||||
{
|
||||
get { return mRawPCMInputMode; }
|
||||
set
|
||||
{
|
||||
mRawPCMInputMode = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// force byte-swapping of input (-x)
|
||||
/// </summary>
|
||||
public bool ForceByteSwappingOfInput
|
||||
{
|
||||
get { return mForceByteSwappingOfInput; }
|
||||
set
|
||||
{
|
||||
mForceByteSwappingOfInput = value;
|
||||
mRawPCMInputMode = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sampling frequency of input file (kHz) - default 44.1 kHz (-s sfreq)
|
||||
/// </summary>
|
||||
public SampleRateFrequency RawPCMInputSampleSize
|
||||
{
|
||||
get { return mRawPCMInputSampleSize; }
|
||||
set
|
||||
{
|
||||
mRawPCMInputSampleSize = value;
|
||||
mRawPCMInputMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// input bit width is w (default 16) (--bitwidth w)
|
||||
/// </summary>
|
||||
public int RawPCMInputSampleRate
|
||||
{
|
||||
get { return mRawPCMInputSampleRate; }
|
||||
set
|
||||
{
|
||||
mRawPCMInputSampleRate = value;
|
||||
mRawPCMInputMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// input file is a MPEG Layer III file (--mp3input)
|
||||
/// </summary>
|
||||
public bool Mp3Input
|
||||
{
|
||||
get { return mMp3Input; }
|
||||
set
|
||||
{
|
||||
mMp3Input = value;
|
||||
if (mMp3Input)
|
||||
mRawPCMInputMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// downmix from stereo to mono file for mono encoding (-a)
|
||||
/// </summary>
|
||||
public bool MonoDownmixing
|
||||
{
|
||||
get { return mMonoDownmixing; }
|
||||
set { mMonoDownmixing = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono (-m)
|
||||
/// </summary>
|
||||
public ChannelMode ChannelMode
|
||||
{
|
||||
get { return mChannelMode; }
|
||||
set { mChannelMode = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// produce a free format bitstream (--freeformat)
|
||||
/// </summary>
|
||||
public bool Freeformat
|
||||
{
|
||||
get { return mFreeFormat; }
|
||||
set { mFreeFormat = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// input=mp3 file, output=wav (--decode)
|
||||
/// </summary>
|
||||
public bool DecodeWav
|
||||
{
|
||||
get { return mDecodeWav; }
|
||||
set { mDecodeWav = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// disable writing wav header when using --decode (-t)
|
||||
/// </summary>
|
||||
public bool DisableWavHeader
|
||||
{
|
||||
get { return mDisableWavHeader; }
|
||||
set
|
||||
{
|
||||
mDisableWavHeader = value;
|
||||
if (mDisableWavHeader)
|
||||
DecodeWav = true;
|
||||
}
|
||||
}
|
||||
|
||||
public BitRate BitRate
|
||||
{
|
||||
get { return mBitRate; }
|
||||
set
|
||||
{
|
||||
mBitRate = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing the command line arguments specified by the properties in the object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string GetCommandLineArguments()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (mRawPCMInputMode)
|
||||
{
|
||||
stringBuilder.Append(" -r");
|
||||
if (mForceByteSwappingOfInput)
|
||||
stringBuilder.Append(" -x");
|
||||
if (mRawPCMInputSampleSize != SampleRateFrequency.Hz_44100)
|
||||
stringBuilder.Append(" -s " + SampleRateFrequencyUtility.GetSampleRateFrequencyInt(mRawPCMInputSampleSize));
|
||||
if (mRawPCMInputSampleRate != 16)
|
||||
stringBuilder.Append(" --bandwidth " + mRawPCMInputSampleRate);
|
||||
}
|
||||
if (mMp3Input)
|
||||
stringBuilder.Append(" --mp3input");
|
||||
if (mMonoDownmixing)
|
||||
stringBuilder.Append(" -a");
|
||||
if (mChannelMode != ChannelMode.JointStereo)
|
||||
stringBuilder.Append(" -m " + ChannelModeUtility.GetChannelModeChar(mChannelMode));
|
||||
|
||||
if (mFreeFormat)
|
||||
{
|
||||
stringBuilder.Append(" --freeformat");
|
||||
stringBuilder.Append(" -b " + BitRateFrequencyUtility.GetBitRateInt(BitRate));
|
||||
}
|
||||
|
||||
if (mDecodeWav)
|
||||
{
|
||||
stringBuilder.Append(" --decode");
|
||||
if (mDisableWavHeader)
|
||||
stringBuilder.Append(" -t");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(mInfile))
|
||||
stringBuilder.Append(" " + GetQuotedCommandLineArgument(mInfile));
|
||||
if (!string.IsNullOrEmpty(mOutfile))
|
||||
stringBuilder.Append(" " + (mOutfile));
|
||||
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Generated
+306
@@ -0,0 +1,306 @@
|
||||
namespace m3uTool
|
||||
{
|
||||
partial class Mp3ToAacBatch
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Mp3ToAacBatch));
|
||||
this.inputListBox = new System.Windows.Forms.ListBox();
|
||||
this.addFolderButton = new System.Windows.Forms.Button();
|
||||
this.addFileButton = new System.Windows.Forms.Button();
|
||||
this.moveUpButton = new System.Windows.Forms.Button();
|
||||
this.moveDownButton = new System.Windows.Forms.Button();
|
||||
this.sortButton = new System.Windows.Forms.Button();
|
||||
this.updownSplitContainer = new System.Windows.Forms.SplitContainer();
|
||||
this.inputLabel = new System.Windows.Forms.Label();
|
||||
this.inputPanel = new System.Windows.Forms.Panel();
|
||||
this.clearButton = new System.Windows.Forms.Button();
|
||||
this.optionsPanel = new System.Windows.Forms.Panel();
|
||||
this.singleFileCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.outputDirectoryTextBox = new System.Windows.Forms.TextBox();
|
||||
this.optionsLabel = new System.Windows.Forms.Label();
|
||||
this.savePanel = new System.Windows.Forms.Panel();
|
||||
this.saveLabel = new System.Windows.Forms.Label();
|
||||
this.updownSplitContainer.Panel1.SuspendLayout();
|
||||
this.updownSplitContainer.Panel2.SuspendLayout();
|
||||
this.updownSplitContainer.SuspendLayout();
|
||||
this.inputPanel.SuspendLayout();
|
||||
this.optionsPanel.SuspendLayout();
|
||||
this.savePanel.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// inputListBox
|
||||
//
|
||||
this.inputListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.inputListBox.FormattingEnabled = true;
|
||||
this.inputListBox.Location = new System.Drawing.Point(6, 35);
|
||||
this.inputListBox.Name = "inputListBox";
|
||||
this.inputListBox.Size = new System.Drawing.Size(551, 264);
|
||||
this.inputListBox.TabIndex = 0;
|
||||
//
|
||||
// addFolderButton
|
||||
//
|
||||
this.addFolderButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.addFolderButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||
this.addFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.addFolderButton.Image = ((System.Drawing.Image)(resources.GetObject("addFolderButton.Image")));
|
||||
this.addFolderButton.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
|
||||
this.addFolderButton.Location = new System.Drawing.Point(470, 3);
|
||||
this.addFolderButton.Name = "addFolderButton";
|
||||
this.addFolderButton.Size = new System.Drawing.Size(87, 30);
|
||||
this.addFolderButton.TabIndex = 2;
|
||||
this.addFolderButton.Text = "Add Folder";
|
||||
this.addFolderButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
|
||||
this.addFolderButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// addFileButton
|
||||
//
|
||||
this.addFileButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.addFileButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||
this.addFileButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.addFileButton.Image = ((System.Drawing.Image)(resources.GetObject("addFileButton.Image")));
|
||||
this.addFileButton.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
|
||||
this.addFileButton.Location = new System.Drawing.Point(390, 3);
|
||||
this.addFileButton.Name = "addFileButton";
|
||||
this.addFileButton.Size = new System.Drawing.Size(74, 30);
|
||||
this.addFileButton.TabIndex = 3;
|
||||
this.addFileButton.Text = "Add File";
|
||||
this.addFileButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
|
||||
this.addFileButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// moveUpButton
|
||||
//
|
||||
this.moveUpButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||
this.moveUpButton.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.moveUpButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.moveUpButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.moveUpButton.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
|
||||
this.moveUpButton.Location = new System.Drawing.Point(0, 0);
|
||||
this.moveUpButton.Name = "moveUpButton";
|
||||
this.moveUpButton.Size = new System.Drawing.Size(18, 107);
|
||||
this.moveUpButton.TabIndex = 4;
|
||||
this.moveUpButton.Text = "^|";
|
||||
this.moveUpButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
|
||||
this.moveUpButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// moveDownButton
|
||||
//
|
||||
this.moveDownButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||
this.moveDownButton.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.moveDownButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.moveDownButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.moveDownButton.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
|
||||
this.moveDownButton.Location = new System.Drawing.Point(0, 0);
|
||||
this.moveDownButton.Name = "moveDownButton";
|
||||
this.moveDownButton.Size = new System.Drawing.Size(18, 157);
|
||||
this.moveDownButton.TabIndex = 5;
|
||||
this.moveDownButton.Text = "|v";
|
||||
this.moveDownButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
|
||||
this.moveDownButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// sortButton
|
||||
//
|
||||
this.sortButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.sortButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||
this.sortButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.sortButton.Image = ((System.Drawing.Image)(resources.GetObject("sortButton.Image")));
|
||||
this.sortButton.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
|
||||
this.sortButton.Location = new System.Drawing.Point(0, 307);
|
||||
this.sortButton.Name = "sortButton";
|
||||
this.sortButton.Size = new System.Drawing.Size(61, 30);
|
||||
this.sortButton.TabIndex = 6;
|
||||
this.sortButton.Text = "Sort";
|
||||
this.sortButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
|
||||
this.sortButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// updownSplitContainer
|
||||
//
|
||||
this.updownSplitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.updownSplitContainer.IsSplitterFixed = true;
|
||||
this.updownSplitContainer.Location = new System.Drawing.Point(563, 35);
|
||||
this.updownSplitContainer.Name = "updownSplitContainer";
|
||||
this.updownSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||
//
|
||||
// updownSplitContainer.Panel1
|
||||
//
|
||||
this.updownSplitContainer.Panel1.Controls.Add(this.moveUpButton);
|
||||
//
|
||||
// updownSplitContainer.Panel2
|
||||
//
|
||||
this.updownSplitContainer.Panel2.Controls.Add(this.moveDownButton);
|
||||
this.updownSplitContainer.Size = new System.Drawing.Size(18, 266);
|
||||
this.updownSplitContainer.SplitterDistance = 107;
|
||||
this.updownSplitContainer.SplitterWidth = 2;
|
||||
this.updownSplitContainer.TabIndex = 8;
|
||||
//
|
||||
// inputLabel
|
||||
//
|
||||
this.inputLabel.AutoSize = true;
|
||||
this.inputLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.inputLabel.Location = new System.Drawing.Point(3, 3);
|
||||
this.inputLabel.Name = "inputLabel";
|
||||
this.inputLabel.Size = new System.Drawing.Size(126, 13);
|
||||
this.inputLabel.TabIndex = 9;
|
||||
this.inputLabel.Text = "1) Select Input MP3s";
|
||||
//
|
||||
// inputPanel
|
||||
//
|
||||
this.inputPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.inputPanel.Controls.Add(this.clearButton);
|
||||
this.inputPanel.Controls.Add(this.inputLabel);
|
||||
this.inputPanel.Controls.Add(this.inputListBox);
|
||||
this.inputPanel.Controls.Add(this.updownSplitContainer);
|
||||
this.inputPanel.Controls.Add(this.addFolderButton);
|
||||
this.inputPanel.Controls.Add(this.addFileButton);
|
||||
this.inputPanel.Controls.Add(this.sortButton);
|
||||
this.inputPanel.Location = new System.Drawing.Point(12, 12);
|
||||
this.inputPanel.Name = "inputPanel";
|
||||
this.inputPanel.Size = new System.Drawing.Size(584, 344);
|
||||
this.inputPanel.TabIndex = 10;
|
||||
//
|
||||
// clearButton
|
||||
//
|
||||
this.clearButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.clearButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||
this.clearButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.clearButton.Image = ((System.Drawing.Image)(resources.GetObject("clearButton.Image")));
|
||||
this.clearButton.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
|
||||
this.clearButton.Location = new System.Drawing.Point(491, 307);
|
||||
this.clearButton.Name = "clearButton";
|
||||
this.clearButton.Size = new System.Drawing.Size(66, 30);
|
||||
this.clearButton.TabIndex = 10;
|
||||
this.clearButton.Text = "Clear";
|
||||
this.clearButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
|
||||
this.clearButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// optionsPanel
|
||||
//
|
||||
this.optionsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.optionsPanel.Controls.Add(this.singleFileCheckBox);
|
||||
this.optionsPanel.Controls.Add(this.outputDirectoryTextBox);
|
||||
this.optionsPanel.Controls.Add(this.optionsLabel);
|
||||
this.optionsPanel.Location = new System.Drawing.Point(12, 362);
|
||||
this.optionsPanel.Name = "optionsPanel";
|
||||
this.optionsPanel.Size = new System.Drawing.Size(584, 135);
|
||||
this.optionsPanel.TabIndex = 11;
|
||||
//
|
||||
// singleFileCheckBox
|
||||
//
|
||||
this.singleFileCheckBox.AutoSize = true;
|
||||
this.singleFileCheckBox.Location = new System.Drawing.Point(448, 12);
|
||||
this.singleFileCheckBox.Name = "singleFileCheckBox";
|
||||
this.singleFileCheckBox.Size = new System.Drawing.Size(109, 17);
|
||||
this.singleFileCheckBox.TabIndex = 12;
|
||||
this.singleFileCheckBox.Text = "Output Single File";
|
||||
this.singleFileCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// outputDirectoryTextBox
|
||||
//
|
||||
this.outputDirectoryTextBox.Location = new System.Drawing.Point(8, 112);
|
||||
this.outputDirectoryTextBox.Name = "outputDirectoryTextBox";
|
||||
this.outputDirectoryTextBox.Size = new System.Drawing.Size(100, 20);
|
||||
this.outputDirectoryTextBox.TabIndex = 11;
|
||||
//
|
||||
// optionsLabel
|
||||
//
|
||||
this.optionsLabel.AutoSize = true;
|
||||
this.optionsLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.optionsLabel.Location = new System.Drawing.Point(3, 0);
|
||||
this.optionsLabel.Name = "optionsLabel";
|
||||
this.optionsLabel.Size = new System.Drawing.Size(105, 13);
|
||||
this.optionsLabel.TabIndex = 10;
|
||||
this.optionsLabel.Text = "2) Select Options";
|
||||
//
|
||||
// savePanel
|
||||
//
|
||||
this.savePanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.savePanel.Controls.Add(this.saveLabel);
|
||||
this.savePanel.Location = new System.Drawing.Point(12, 503);
|
||||
this.savePanel.Name = "savePanel";
|
||||
this.savePanel.Size = new System.Drawing.Size(584, 93);
|
||||
this.savePanel.TabIndex = 12;
|
||||
//
|
||||
// saveLabel
|
||||
//
|
||||
this.saveLabel.AutoSize = true;
|
||||
this.saveLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.saveLabel.Location = new System.Drawing.Point(3, 0);
|
||||
this.saveLabel.Name = "saveLabel";
|
||||
this.saveLabel.Size = new System.Drawing.Size(79, 13);
|
||||
this.saveLabel.TabIndex = 10;
|
||||
this.saveLabel.Text = "3) Save AAC";
|
||||
//
|
||||
// Mp3ToAacBatch
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(608, 608);
|
||||
this.Controls.Add(this.savePanel);
|
||||
this.Controls.Add(this.optionsPanel);
|
||||
this.Controls.Add(this.inputPanel);
|
||||
this.Name = "Mp3ToAacBatch";
|
||||
this.Text = "Mp3 To AAC Batch";
|
||||
this.updownSplitContainer.Panel1.ResumeLayout(false);
|
||||
this.updownSplitContainer.Panel2.ResumeLayout(false);
|
||||
this.updownSplitContainer.ResumeLayout(false);
|
||||
this.inputPanel.ResumeLayout(false);
|
||||
this.inputPanel.PerformLayout();
|
||||
this.optionsPanel.ResumeLayout(false);
|
||||
this.optionsPanel.PerformLayout();
|
||||
this.savePanel.ResumeLayout(false);
|
||||
this.savePanel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ListBox inputListBox;
|
||||
private System.Windows.Forms.Button addFolderButton;
|
||||
private System.Windows.Forms.Button addFileButton;
|
||||
private System.Windows.Forms.Button moveUpButton;
|
||||
private System.Windows.Forms.Button moveDownButton;
|
||||
private System.Windows.Forms.Button sortButton;
|
||||
private System.Windows.Forms.SplitContainer updownSplitContainer;
|
||||
private System.Windows.Forms.Label inputLabel;
|
||||
private System.Windows.Forms.Panel inputPanel;
|
||||
private System.Windows.Forms.Panel optionsPanel;
|
||||
private System.Windows.Forms.Label optionsLabel;
|
||||
private System.Windows.Forms.Button clearButton;
|
||||
private System.Windows.Forms.Panel savePanel;
|
||||
private System.Windows.Forms.Label saveLabel;
|
||||
private System.Windows.Forms.TextBox outputDirectoryTextBox;
|
||||
private System.Windows.Forms.CheckBox singleFileCheckBox;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
public partial class Mp3ToAacBatch : Form
|
||||
{
|
||||
public Mp3ToAacBatch()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="addFolderButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAO9JREFUOE9jYKAW
|
||||
OLdI8T8yJslckEZ0cGyWxH+iDAEphIA5aPj/f5AcNoxiMNiAz0DNn3swMYa7IIbOrZJEuA5swOuW/48O
|
||||
+uO0EZsrlhbxQAwBG3C9Baz51v5shJ2/v2OxHyj0vAUsjmLA36v5YAO+f+jEEhZoYXM86v/vn9NQDXi0
|
||||
2en/yQUKIHP///8+BS9+vi/o/7k90agGnF+k+v/6DnuI7cDwwImBzn+/ywmhGRYGx2ZJ/v/wpBJiwONq
|
||||
3Ph+9f97m7AYcHyONETzdWAgEsD7Z2qgugDkigPTJP4Ti+dU4kihIAliMFHJm66KAORP5xRdT7ByAAAA
|
||||
AElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="addFileButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAiJJREFUOE+Nk+1L
|
||||
U1Ecx/WP6v1e9d53azYqIogixAcoR2+UjErQIFjSWgZbLJnkbPMur+7pzm3OPXhRvDp0TndxbKV7cLt7
|
||||
cGtf77ntgrVLdeBwD4f7+Xx/P845vT2dEYwdQl7/7buePusZ6rvW2/WPcymEP0e7DTRbP1FvtiA0WqBj
|
||||
x5haiEjzn4K2SMfjSRgM8zjiczivNfHMuY/rln30vXB0S65WQGCS7PWxePJ4Enduj8Hl20OuUEYyVwLl
|
||||
4qDT6X6vQhbIcP2iBbd3Ax+MFEZHLRgZmcUqwyJTrIn7HDQaTbeAwBekZxGu1JvgEjzs9k3M26LQ3nyK
|
||||
twYr+HwVzBoHtVrdLbgKl6pNFIQGlukd+EK70L+bg83px9GpAH9gR1lQ6yRLcKWBH+UGnMuboD1x7PGn
|
||||
EnzwvQKff1tZQMomcL4DZ0s1LFIBfPq8glQHTmTL8DBbygIZTqTyoFcTMJkCeHB/AtPTFimZwFymDJeX
|
||||
VRbIyeFIGsWiAMZ/gMGB5xgefAlKPFIuc47tkxJod1xZQHpmuSysVgbhcBJmswe3tMOYfGXCV3dMglm+
|
||||
iG+uqLKA9BzZ4qHtH8K9uzr03xjAo4fjmJlZhJc9lODocQHUyoay4KRQRfpMwNTrOYyPGWB8vwS9/gvM
|
||||
Ni/Y9C84nCrAQYeVBaH1BNaCu2DEc/4464DRsAA7FZR6JmWTZAK/Ed9H10Uir4tsqlSq/5qy4BL8gXM2
|
||||
KgxAeQAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="sortButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAOJJREFUOE+9UrkN
|
||||
wzAM9Cbps4SnYO1RNIq7FFwirlOnzBDeQLkTSUOGAkhJEQOEbIP38Khp+seja863x56plZJm1le6umom
|
||||
iYFxLoMEzzuaAVScRmAlIBhywiYCCxggWeQAk+R6kf4oRQkEMlvz9tpAYi5OOYRSHZRZNrsEMIt45/eJ
|
||||
xAhiNlMoBeXkija7Z8AR6IrrUfws5xEUGj0ocfUgk9mB4T/5imJNEVQ4YFC1XfY388d+iyUPKmx3L8zn
|
||||
oKoMepfGZkNVszZBdW2ggSQMjmM0QQ0RVHvlOpugRkh+6XkD9f86XlAO9kEAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="clearButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAh1JREFUOE+Vk1tP
|
||||
E1EUhaeY8L+M/6WPPpgYYzTG6INEEo0aQBo00ShBjRhTi1UsUFqx1SLQG/RGL1AK0wu92jJnziz3Hm0k
|
||||
meHBSU5mkplvrW+fyXEof687r7IYPp++O0ZGFH0wUM6Njip5313F5XI57L5TOIAvYQADAfQ0A62BgcYv
|
||||
A7WOBL+/4lbhdDpti8wAIYE+wd0TgvsG6j0DVYIrLYkLs31znX9YsA/hgL4GdKi1ya1dA0dtAwcEl44l
|
||||
IgmY67W7hxtjbmsIB7RZmVprXYnDtkS5SXBDYrcmkVYldg51xA90fA537QPqPQm1Y6BC8D61FutDWMc2
|
||||
wTGCN/d1+NY79gEqzcvKewTnCc5WdaSOJJIViVhZxwbBP4pkEDkjoNw0UCTlPClnqqRMcIJatwj+uSfw
|
||||
neBveYGP4bbV4PbzBAoE5xhW/ylvUet6iWGBNYIDOQFPyCbg5swGcqTMm5Ws/JmXlSMlHeECwbsCq1mB
|
||||
5YyG919bVoPrEyFzl1k5airzvAIhgoME+7MallICizsa3gWa1oCr91cRp2ZWZng4b5BaVzICX9IaPm0L
|
||||
LCQE3vhtAi6PLVqUA6ycJpiavUkNngTpxzTMLR9bDS7d8pi/aKjM8y5RKyt7qflDnODoCeY3Nbz0NawB
|
||||
F6/N48nbFFxzSTyejWHqRRTTzyKYehrG5MwaJqaDeDTpx/iDBYzf89qfBz5p/7P4WP8G/jqMg6Vn2nUA
|
||||
AAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
public class Mp4Encoder : ProcessStreamWrapper
|
||||
{
|
||||
public Mp4Encoder(Mp4EncodingOptions encOpt) : base(encOpt)
|
||||
{
|
||||
}
|
||||
|
||||
public Mp4Encoder(Mp4EncodingOptions encOpt, Stream outputStream)
|
||||
: base(encOpt, outputStream)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string ProcessExecutableFilename
|
||||
{
|
||||
get { return "faac.exe"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,527 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
/// <summary>
|
||||
///FAAC 1.24.1 (May 17 2005) UNSTABLE
|
||||
///
|
||||
///Usage: faac [options] infiles ...
|
||||
///Options:
|
||||
/// -q <quality> Set quantizer quality.
|
||||
/// -b <bitrate> Set average bitrate to x kbps. (ABR, lower quality mode)
|
||||
/// -c <freq> Set the bandwidth in Hz. (default=automatic)
|
||||
/// -o X Set output file to X (only for one input file)
|
||||
/// -r Use RAW AAC output file.
|
||||
/// -P Raw PCM input mode (default 44100Hz 16bit stereo).
|
||||
/// -R Raw PCM input rate.
|
||||
/// -B Raw PCM input sample size (8, 16 (default), 24 or 32bits).
|
||||
/// -C Raw PCM input channels.
|
||||
/// -X Raw PCM swap input bytes
|
||||
/// -I <C,LF> Input channel config, default is 3,4 (Center third, LF fourth)
|
||||
///
|
||||
///MP4 specific options:
|
||||
/// -w Wrap AAC data in MP4 container. (default for *.mp4 and *.m4a)
|
||||
/// --artist X Set artist to X
|
||||
/// --writer X Set writer to X
|
||||
/// --title X Set title to X
|
||||
/// --genre X Set genre to X
|
||||
/// --album X Set album to X
|
||||
/// --compilation Set compilation
|
||||
/// --track X Set track to X (number/total)
|
||||
/// --disc X Set disc to X (number/total)
|
||||
/// --year X Set year to X
|
||||
/// --cover-art X Read cover art from file X
|
||||
/// --comment X Set comment to X
|
||||
/// </summary>
|
||||
public class Mp4EncodingOptions : ProcessArguments
|
||||
{
|
||||
#region Private variables
|
||||
|
||||
/// <summary>
|
||||
/// Files to use for input
|
||||
/// </summary>
|
||||
private string[] mInfiles;
|
||||
|
||||
/// <summary>
|
||||
/// Quantinizer Quality -q [quality]
|
||||
/// </summary>
|
||||
private int mQuantinizerQuality = int.MinValue;
|
||||
/// <summary>
|
||||
/// BitRate -b [bitrate]
|
||||
/// </summary>
|
||||
private int mBitrate = int.MinValue;
|
||||
/// <summary>
|
||||
/// The bandwidth in Hz -c [freq]
|
||||
/// </summary>
|
||||
private SampleRateFrequency mBandwidth = SampleRateFrequency.Hz_0;
|
||||
|
||||
/// <summary>
|
||||
/// The output filename (only for one input file) -o [filename]
|
||||
/// </summary>
|
||||
private string mOutputFilename = null;
|
||||
|
||||
/// <summary>
|
||||
/// Use RAW AAC output file -r
|
||||
/// </summary>
|
||||
private bool mRawAACOutputFile = false;
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCM input mode (default 44100Hz 16bit stereo) -P
|
||||
/// </summary>
|
||||
private bool mRawPCMInputMode = false;
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCMInputSampleSize (default 44100Hz 16bit stereo) -R
|
||||
/// </summary>
|
||||
private SampleRateFrequency mRawPCMInputSampleSize = SampleRateFrequency.Hz_44100;
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCM input rate (default 16) -B
|
||||
/// </summary>
|
||||
private int mRawPCMInputSampleRate = 16;
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCM input channels -C
|
||||
/// </summary>
|
||||
private ChannelMode mRawInputChannels;
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCM swap input bytes -X
|
||||
/// </summary>
|
||||
private bool mRawPCMSwapInputBytes = false;
|
||||
|
||||
/// <summary>
|
||||
/// Wrap AAC data in MP4 container. (default for *.mp4 and *.m4a) -w
|
||||
/// </summary>
|
||||
private bool mWrapAACDataInMp4 = false;
|
||||
|
||||
/// <summary>
|
||||
/// Set artist to X --artist X
|
||||
/// </summary>
|
||||
private string mArtist = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set writer to X --writer X
|
||||
/// </summary>
|
||||
private string mWriter = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set title to X --title X
|
||||
/// </summary>
|
||||
private string mTitle = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set genre to X --genre X
|
||||
/// </summary>
|
||||
private string mGenre = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set album to X --album X
|
||||
/// </summary>
|
||||
private string mAlbum = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set compilation --compilation
|
||||
/// </summary>
|
||||
private string mCompilation = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set track to X (number/total) --track X
|
||||
/// </summary>
|
||||
private string mTrack = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set disc to X (number/total) --disc X
|
||||
/// </summary>
|
||||
private string mDisc = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set year to X --year X
|
||||
/// </summary>
|
||||
private int mYear = int.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Load cover art from filename --cover-art X
|
||||
/// </summary>
|
||||
private string mCoverArtFilename = null;
|
||||
|
||||
/// <summary>
|
||||
/// Set comment to X --comment X
|
||||
/// </summary>
|
||||
private string mComment = null;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the input files.
|
||||
/// </summary>
|
||||
/// <value>The input files.</value>
|
||||
public string[] InputFiles
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mInfiles == null)
|
||||
return new string[]{};
|
||||
return mInfiles;
|
||||
}
|
||||
set
|
||||
{
|
||||
mInfiles = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quantinizer Quality -q [quality]
|
||||
/// </summary>
|
||||
public int QuantinizerQuality
|
||||
{
|
||||
get { return mQuantinizerQuality; }
|
||||
set { mQuantinizerQuality = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BitRate -b [bitrate]
|
||||
/// </summary>
|
||||
public int Bitrate
|
||||
{
|
||||
get { return mBitrate; }
|
||||
set { mBitrate = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The bandwidth in Hz -c [freq]
|
||||
/// </summary>
|
||||
public SampleRateFrequency Bandwidth
|
||||
{
|
||||
get { return mBandwidth; }
|
||||
set { mBandwidth = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The output filename (only for one input file) -o [filename]
|
||||
/// </summary>
|
||||
public string OutputFilename
|
||||
{
|
||||
get { return mOutputFilename; }
|
||||
set { mOutputFilename = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use RAW AAC output file -r
|
||||
/// </summary>
|
||||
public bool RawAACOutputFile
|
||||
{
|
||||
get { return mRawAACOutputFile; }
|
||||
set { mRawAACOutputFile = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCM input mode (default 44100Hz 16bit stereo) -P
|
||||
/// </summary>
|
||||
public bool RawPCMInputMode
|
||||
{
|
||||
get { return mRawPCMInputMode; }
|
||||
set { mRawPCMInputMode = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCMInputSampleSize -R
|
||||
/// </summary>
|
||||
public SampleRateFrequency RawPCMInputSampleSize
|
||||
{
|
||||
get { return mRawPCMInputSampleSize; }
|
||||
set
|
||||
{
|
||||
mRawPCMInputSampleSize = value;
|
||||
RawPCMInputMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCM input rate (default 16) -B
|
||||
/// </summary>
|
||||
public int RawPCMInputSampleRate
|
||||
{
|
||||
get { return mRawPCMInputSampleRate; }
|
||||
set
|
||||
{
|
||||
mRawPCMInputSampleRate = value;
|
||||
RawPCMInputMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCM input channels -C
|
||||
/// </summary>
|
||||
public ChannelMode RawInputChannels
|
||||
{
|
||||
get { return mRawInputChannels; }
|
||||
set
|
||||
{
|
||||
mRawInputChannels = value;
|
||||
RawPCMInputMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raw PCM swap input bytes -X
|
||||
/// </summary>
|
||||
public bool RawPCMSwapInputBytes
|
||||
{
|
||||
get { return mRawPCMSwapInputBytes; }
|
||||
set
|
||||
{
|
||||
mRawPCMSwapInputBytes = value;
|
||||
RawPCMInputMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrap AAC data in MP4 container. (default for *.mp4 and *.m4a)
|
||||
/// </summary>
|
||||
public bool WrapAACDataInMp4
|
||||
{
|
||||
get { return mWrapAACDataInMp4; }
|
||||
set { mWrapAACDataInMp4 = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set artist to X
|
||||
/// </summary>
|
||||
public string Artist
|
||||
{
|
||||
get { return mArtist; }
|
||||
set
|
||||
{
|
||||
mArtist = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set writer to X
|
||||
/// </summary>
|
||||
public string Writer
|
||||
{
|
||||
get { return mWriter; }
|
||||
set
|
||||
{
|
||||
mWriter = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set title to X
|
||||
/// </summary>
|
||||
public string Title
|
||||
{
|
||||
get { return mTitle; }
|
||||
set
|
||||
{
|
||||
mTitle = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set genre to X
|
||||
/// </summary>
|
||||
public string Genre
|
||||
{
|
||||
get { return mGenre; }
|
||||
set
|
||||
{
|
||||
mGenre = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set album to X
|
||||
/// </summary>
|
||||
public string Album
|
||||
{
|
||||
get { return mAlbum; }
|
||||
set
|
||||
{
|
||||
mAlbum = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set compilation
|
||||
/// </summary>
|
||||
public string Compilation
|
||||
{
|
||||
get { return mCompilation; }
|
||||
set
|
||||
{
|
||||
mCompilation = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set track to X (number/total)
|
||||
/// </summary>
|
||||
public string Track
|
||||
{
|
||||
get { return mTrack; }
|
||||
set
|
||||
{
|
||||
mTrack = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set disc to X (number/total)
|
||||
/// </summary>
|
||||
public string Disc
|
||||
{
|
||||
get { return mDisc; }
|
||||
set
|
||||
{
|
||||
mDisc = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set year to X
|
||||
/// </summary>
|
||||
public int Year
|
||||
{
|
||||
get { return mYear; }
|
||||
set
|
||||
{
|
||||
mYear = value;
|
||||
if (value != int.MinValue)
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load cover art from filename
|
||||
/// </summary>
|
||||
public string CoverArtFilename
|
||||
{
|
||||
get { return mCoverArtFilename; }
|
||||
set
|
||||
{
|
||||
mCoverArtFilename = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quantinizer Quality -q [quality]
|
||||
/// </summary>
|
||||
public string Comment
|
||||
{
|
||||
get { return mComment; }
|
||||
set
|
||||
{
|
||||
mComment = value;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
WrapAACDataInMp4 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing the command line arguments specified by the properties in the object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string GetCommandLineArguments()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (mQuantinizerQuality != int.MinValue)
|
||||
stringBuilder.Append(" -q " + mQuantinizerQuality);
|
||||
if (mBitrate != int.MinValue)
|
||||
stringBuilder.Append(" -b " + mBitrate);
|
||||
if (mBandwidth != SampleRateFrequency.Hz_0)
|
||||
stringBuilder.Append(" -c " + SampleRateFrequencyUtility.GetSampleRateFrequencyInt(mBandwidth));
|
||||
|
||||
if (!string.IsNullOrEmpty(mOutputFilename))
|
||||
{
|
||||
if (mOutputFilename.Trim() == "-")
|
||||
stringBuilder.Append(" -o-");
|
||||
else
|
||||
stringBuilder.Append(" -o " + GetQuotedCommandLineArgument(mOutputFilename));
|
||||
}
|
||||
else
|
||||
stringBuilder.Append(" -o-");
|
||||
|
||||
if (mRawPCMInputMode)
|
||||
{
|
||||
stringBuilder.Append(" -P ");
|
||||
if (mRawPCMInputSampleSize != SampleRateFrequency.Hz_44100)
|
||||
stringBuilder.Append(" -R " + SampleRateFrequencyUtility.GetSampleRateFrequencyInt(mRawPCMInputSampleSize));
|
||||
if (mRawPCMInputSampleRate != 16)
|
||||
stringBuilder.Append(" -B " + mRawPCMInputSampleRate);
|
||||
int chanelMode = ChannelModeUtility.GetChannelModeInt(mRawInputChannels);
|
||||
if (chanelMode != 2)
|
||||
stringBuilder.Append(" -C " + chanelMode);
|
||||
if (mRawPCMSwapInputBytes)
|
||||
stringBuilder.Append(" -X ");
|
||||
}
|
||||
|
||||
if (mWrapAACDataInMp4)
|
||||
{
|
||||
stringBuilder.Append(" -w ");
|
||||
if (!string.IsNullOrEmpty(mArtist))
|
||||
stringBuilder.Append(" --artist " + mArtist);
|
||||
if (!string.IsNullOrEmpty(mWriter))
|
||||
stringBuilder.Append(" --writer " + mWriter);
|
||||
if (!string.IsNullOrEmpty(mTitle))
|
||||
stringBuilder.Append(" --title " + mTitle);
|
||||
if (!string.IsNullOrEmpty(mGenre))
|
||||
stringBuilder.Append(" --genre " + mGenre);
|
||||
if (!string.IsNullOrEmpty(mAlbum))
|
||||
stringBuilder.Append(" --album " + mAlbum);
|
||||
if (!string.IsNullOrEmpty(mCompilation))
|
||||
stringBuilder.Append(" --compilation " + mCompilation);
|
||||
if (!string.IsNullOrEmpty(mTrack))
|
||||
stringBuilder.Append(" --track " + mTrack);
|
||||
if (!string.IsNullOrEmpty(mDisc))
|
||||
stringBuilder.Append(" --disc " + mDisc);
|
||||
if (mYear != int.MinValue)
|
||||
stringBuilder.Append(" --year " + mYear);
|
||||
if (!string.IsNullOrEmpty(mCoverArtFilename))
|
||||
stringBuilder.Append(" --cover-art " + mCoverArtFilename);
|
||||
if (!string.IsNullOrEmpty(mComment))
|
||||
stringBuilder.Append(" --comment " + mComment);
|
||||
}
|
||||
if (mInfiles != null && mInfiles.Length > 0)
|
||||
{
|
||||
// use standard input
|
||||
if (mInfiles[0].Trim() == "-")
|
||||
stringBuilder.Append(" -");
|
||||
else
|
||||
{
|
||||
foreach (string infile in mInfiles)
|
||||
stringBuilder.Append(" " + GetQuotedCommandLineArgument(infile));
|
||||
}
|
||||
}
|
||||
else
|
||||
stringBuilder.Append(" -");
|
||||
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
public class ProcessArguments
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a string representing the command line arguments specified by the properties in the object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual string GetCommandLineArguments()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
protected string GetQuotedCommandLineArgument(string argument)
|
||||
{
|
||||
if (argument.Contains(" ") || argument.Contains("\t"))
|
||||
{
|
||||
return "\"" + argument + "\"";
|
||||
}
|
||||
return argument;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,365 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
/// <summary>
|
||||
/// A generic encoder. Creates an external process, sends it argument options,
|
||||
/// and acts as a wrapper for streaming reads and writes
|
||||
/// </summary>
|
||||
public abstract class ProcessStreamWrapper : IDisposable
|
||||
{
|
||||
#region Protected Variables
|
||||
/// <summary>
|
||||
/// The arguments to use for the process
|
||||
/// </summary>
|
||||
protected ProcessArguments mProcessArguments;
|
||||
|
||||
/// <summary>
|
||||
/// The process
|
||||
/// </summary>
|
||||
protected Process mProcess;
|
||||
|
||||
/// <summary>
|
||||
/// How much data to buffer when reading and writing
|
||||
/// </summary>
|
||||
protected const int mBufferLength = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// The output stream writer. If it is null, it is assumed
|
||||
/// that the process will take care of output itself.
|
||||
/// </summary>
|
||||
protected StreamWriter mOutputStreamWriter = null;
|
||||
|
||||
/// <summary>
|
||||
/// Progress call-back, for status updates outside this class.
|
||||
/// </summary>
|
||||
protected IProgressCallback mProgressCallback = new DoNothingProgressCallback();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the progress callback.
|
||||
/// </summary>
|
||||
/// <value>The progress callback.</value>
|
||||
public IProgressCallback ProgressCallback
|
||||
{
|
||||
get { return mProgressCallback; }
|
||||
set { mProgressCallback = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the process executable filename, such as "LAME.EXE", "FAAC.EXE", etc.
|
||||
/// </summary>
|
||||
/// <value>The process executable filename.</value>
|
||||
protected abstract string ProcessExecutableFilename
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ProcessStreamWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="encOpt">The enc opt.</param>
|
||||
public ProcessStreamWrapper(ProcessArguments encOpt) : this (encOpt, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ProcessStreamWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="encOpt">The enc opt.</param>
|
||||
/// <param name="outputStream">Output to this stream</param>
|
||||
public ProcessStreamWrapper(ProcessArguments encOpt, Stream outputStream)
|
||||
{
|
||||
mProcessArguments = encOpt;
|
||||
|
||||
mProcess = CreateProcess(mProcessArguments, ProcessExecutableFilename);
|
||||
if (outputStream != null)
|
||||
{
|
||||
mOutputStreamWriter = new StreamWriter(outputStream, Encoding.Default);
|
||||
mProcess.StartInfo.RedirectStandardOutput = true;
|
||||
mProcess.StartInfo.StandardOutputEncoding = Encoding.Default;
|
||||
}
|
||||
mProcess.StartInfo.RedirectStandardError = true;
|
||||
|
||||
mProcess.Exited += new EventHandler(Process_Exited);
|
||||
mProcess.Start();
|
||||
if (mOutputStreamWriter != null)
|
||||
{
|
||||
Thread thread = new Thread(new ThreadStart(GetStandardOutput));
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
Thread standardErrorThread = new Thread(new ThreadStart(GetStandardError));
|
||||
standardErrorThread.Start();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates a process given an executable and some process arguments
|
||||
/// </summary>
|
||||
/// <param name="processArguments">The enc opt.</param>
|
||||
/// <param name="executable">The executable filename.</param>
|
||||
/// <returns></returns>
|
||||
private static Process CreateProcess(ProcessArguments processArguments, string executable)
|
||||
{
|
||||
Process process = new Process();
|
||||
process.StartInfo.RedirectStandardInput = true;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.FileName = executable;
|
||||
process.StartInfo.Arguments = processArguments.GetCommandLineArguments();
|
||||
process.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
|
||||
process.EnableRaisingEvents = true;
|
||||
return process;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handlers
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Exited event of the Process.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
|
||||
void Process_Exited(object sender, EventArgs e)
|
||||
{
|
||||
mProgressCallback.SetText("Process_Exited");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utility methods
|
||||
|
||||
private static int GetPercentDone(long previousLeft, long currentLeft, long currentDone, int lastDone)
|
||||
{
|
||||
// if currentLeft > previousLeft - lastDone,
|
||||
// addedLeft = previousLeft - lastDone - currentLeft
|
||||
// totalLength = previousLeft + currentDone + addedLeft
|
||||
|
||||
long totalLength = currentLeft;
|
||||
if (currentLeft != previousLeft)
|
||||
{
|
||||
long leftDelta = previousLeft - lastDone - currentLeft;
|
||||
totalLength = previousLeft + currentDone + leftDelta;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Convert.ToInt32((currentDone / (double)totalLength) * 100);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.ToString());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
|
||||
/// <summary>
|
||||
/// Sends the data to the underlying process through its input stream.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The data to encode</param>
|
||||
/// <param name="count">How many characters to write</param>
|
||||
/// <param name="startIndex">The index to begin writing from</param>
|
||||
public void ProcessInput(char[] buffer, int startIndex, int count)
|
||||
{
|
||||
mProcess.StandardInput.Write(buffer, startIndex, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the data from the input stream to the process
|
||||
/// </summary>
|
||||
/// <param name="inputStream"></param>
|
||||
public void ProcessInput(Stream inputStream)
|
||||
{
|
||||
if (!inputStream.CanRead)
|
||||
throw new ArgumentException("Can't read from inputStream");
|
||||
|
||||
mProgressCallback.SetText("ProcessInput: StreamReader sr");
|
||||
|
||||
long inputCount = inputStream.Length;
|
||||
long previousInputCount = inputStream.Length;
|
||||
long wroteCount = 0;
|
||||
int percentageComplete = 0;
|
||||
|
||||
StreamReader sr = new StreamReader(inputStream, Encoding.Default);
|
||||
//using (StreamReader sr = new StreamReader(inputStream, Encoding.Default))
|
||||
{
|
||||
mProgressCallback.Begin(0, 100);
|
||||
mProgressCallback.SetText(mProcessArguments.GetCommandLineArguments());
|
||||
|
||||
char[] buffer = new char[mBufferLength];
|
||||
|
||||
while (!sr.EndOfStream)
|
||||
{
|
||||
int readLength = sr.Read(buffer, 0, mBufferLength);
|
||||
ProcessInput(buffer, 0, readLength);
|
||||
|
||||
// update progress
|
||||
wroteCount += readLength;
|
||||
previousInputCount = inputCount;
|
||||
inputCount = inputStream.Length;
|
||||
int currentPercentageComplete = GetPercentDone(previousInputCount, inputCount, wroteCount, readLength);
|
||||
if (currentPercentageComplete != percentageComplete)
|
||||
{
|
||||
percentageComplete = currentPercentageComplete;
|
||||
mProgressCallback.StepTo(percentageComplete);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
mInputDone = true;
|
||||
mProgressCallback.SetText("ProcessInput: Done. " + String.Format("Wrote: {0}", wroteCount));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Open this file and encode it.
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
public void ProcessInput(string filename)
|
||||
{
|
||||
using (FileStream inputStream = File.OpenRead(filename))
|
||||
{
|
||||
ProcessInput(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Threaded methods
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TEMP: this should be removed once GetStandardOutput is working
|
||||
/// </summary>
|
||||
bool mInputDone = false;
|
||||
|
||||
/// <summary>
|
||||
/// Collects all the data from Process.StandardOutput and sends it to the outputstream writer
|
||||
/// </summary>
|
||||
private void GetStandardOutput()
|
||||
{
|
||||
int readTotal = 0;
|
||||
char[] writeBuffer = new char[mBufferLength];
|
||||
|
||||
try
|
||||
{
|
||||
while (!mProcess.StandardOutput.EndOfStream)
|
||||
//while (mProcess.StandardOutput.Peek() > -1)
|
||||
{
|
||||
mProgressCallback.SetText("- Before read");
|
||||
int readLength = mProcess.StandardOutput.Read(writeBuffer, 0, writeBuffer.Length);
|
||||
mProgressCallback.SetText("- After read: " + readLength);
|
||||
mOutputStreamWriter.Write(writeBuffer, 0, readLength);
|
||||
if (mInputDone)
|
||||
mProgressCallback.SetText(" StandardOutput: " + new string(writeBuffer, 0, readLength));
|
||||
readTotal += readLength;
|
||||
mProgressCallback.SetText("Read total = " + readTotal);
|
||||
|
||||
//mProcess.StandardInput.Flush();
|
||||
//mProcess.StandardOutput.BaseStream.Flush();
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
mProgressCallback.SetText(ex.ToString());
|
||||
}
|
||||
// mOutputStreamWriter.Flush();
|
||||
mProgressCallback.SetText("GetStandardOutput() " + "Done!" + " StandardOutput.EndOfStream = " + mProcess.StandardOutput.EndOfStream);
|
||||
}
|
||||
|
||||
/* Asynchronous implementation of GetStandardOutput
|
||||
//int mReadTotal = 0;
|
||||
//private byte[] mBuffer = new byte[mBufferLength];
|
||||
//private void GetStandardOutputAsync()
|
||||
//{
|
||||
// mProcess.StandardOutput.BaseStream.BeginRead(mBuffer, 0, mBufferLength, GetStandardOutputCallback, 0);
|
||||
//}
|
||||
|
||||
//private void GetStandardOutputCallback(IAsyncResult asyncResult)
|
||||
//{
|
||||
// mProgressCallback.SetText("- Before read:");
|
||||
// int readLength = mProcess.StandardOutput.BaseStream.EndRead(asyncResult);
|
||||
// mProgressCallback.SetText("- After read:" + readLength);
|
||||
// mOutputStreamWriter.BaseStream.Write(mBuffer, 0, readLength);
|
||||
// mReadTotal += readLength;
|
||||
// mProgressCallback.SetText("Read total = " + mReadTotal);
|
||||
// mProcess.StandardOutput.BaseStream.BeginRead(mBuffer, 0, mBufferLength, GetStandardOutputCallback, 0);
|
||||
//}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Collects all the data from Process.StandardError and sends it to the progress callback
|
||||
/// </summary>
|
||||
private void GetStandardError()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!mProcess.StandardError.EndOfStream)
|
||||
{
|
||||
string line = mProcess.StandardError.ReadLine();
|
||||
mProgressCallback.SetText("GetStandardError() " + line);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
mProgressCallback.SetText(ex.ToString());
|
||||
}
|
||||
mProgressCallback.SetText("GetStandardError() " + "Done!");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
int count = 0;
|
||||
mProgressCallback.SetText("Dispose()");
|
||||
while (mProcess != null && !mProcess.HasExited)
|
||||
{
|
||||
mProcess.WaitForExit(2);
|
||||
if (count++ > mBufferLength && !mProcess.HasExited)
|
||||
{
|
||||
mProcess.Kill();
|
||||
mProgressCallback.SetText("!!! Process.Kill()");
|
||||
}
|
||||
else
|
||||
{
|
||||
// mProgressCallback.SetText("Writing EOF");
|
||||
mProcess.StandardInput.Write(new string(new char[] { (char)0x1A, '\n' }));
|
||||
}
|
||||
}
|
||||
|
||||
mProgressCallback.SetText("Dispose() with exit code " + mProcess.ExitCode);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Generated
+63
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:2.0.50727.42
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace m3uTool.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("m3uTool.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool
|
||||
{
|
||||
[Flags]
|
||||
public enum Redirect
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not redirect anything
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// Redirect standard input
|
||||
/// </summary>
|
||||
StandardInput = 1,
|
||||
/// <summary>
|
||||
/// Redirect standard output
|
||||
/// </summary>
|
||||
StandardOutput = 2,
|
||||
/// <summary>
|
||||
/// Redirect standart error
|
||||
/// </summary>
|
||||
StandardError = 4
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StdinToStdout
|
||||
{
|
||||
/// <summary>
|
||||
/// Simply takes anything from standard input and writes it directly to standard output.
|
||||
/// </summary>
|
||||
public class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Stream inputStream = Console.OpenStandardInput(1);
|
||||
Stream outputStream = Console.OpenStandardOutput(1);
|
||||
// Stream errorStream = Console.OpenStandardError();
|
||||
using (StreamReader sr = new StreamReader(inputStream, Encoding.Default))
|
||||
using (StreamWriter sw = new StreamWriter(outputStream, Encoding.Default))
|
||||
{
|
||||
char[] buffer = new char[1];
|
||||
while (!sr.EndOfStream)
|
||||
{
|
||||
int readLength = sr.Read(buffer, 0, 1);
|
||||
sw.Write(buffer, 0, readLength);
|
||||
}
|
||||
inputStream.Flush();
|
||||
outputStream.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("StdinToStdout")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("StdinToStdout")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2006")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("63522965-dbbf-40a5-a4d3-5ed1ec25b611")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,47 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{94C7033C-C8A8-4104-95FE-0D11122080E2}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>StdinToStdout</RootNamespace>
|
||||
<AssemblyName>StdinToStdout</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for CreateM3uTest.
|
||||
/// </summary>
|
||||
public class CreateM3uTests
|
||||
{
|
||||
public void CreateM3uTest()
|
||||
{
|
||||
M3uCreate c = new M3uCreate(new DirectoryInfo(@"C:\mp3\"));
|
||||
// c.OutputFilename = @"c:\mym3u.m3u";
|
||||
Debug.WriteLine(c.OutputFilename);
|
||||
c.Create();
|
||||
}
|
||||
|
||||
public void CreateSubM3uTest()
|
||||
{
|
||||
DirectoryInfo rootDir = new DirectoryInfo(@"C:\mp3\");
|
||||
|
||||
int count = 0;
|
||||
foreach (DirectoryInfo subDir in rootDir.GetDirectories())
|
||||
{
|
||||
M3uCreate c = new M3uCreate(subDir);
|
||||
|
||||
Debug.WriteLine(c.OutputFilename);
|
||||
c.Create();
|
||||
|
||||
if (count++ > 10)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// c.OutputFilename = @"c:\mym3u.m3u";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
|
||||
namespace Win32
|
||||
{
|
||||
internal class HiPerfTimer
|
||||
{
|
||||
[DllImport("Kernel32.dll")]
|
||||
private static extern bool QueryPerformanceCounter(
|
||||
out long lpPerformanceCount);
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
private static extern bool QueryPerformanceFrequency(
|
||||
out long lpFrequency);
|
||||
|
||||
private long startTime, stopTime;
|
||||
private long freq;
|
||||
|
||||
// Constructor
|
||||
public HiPerfTimer()
|
||||
{
|
||||
startTime = 0;
|
||||
stopTime = 0;
|
||||
|
||||
if (QueryPerformanceFrequency(out freq) == false)
|
||||
{
|
||||
// high-performance counter not supported
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
|
||||
// Start the timer
|
||||
public void Start()
|
||||
{
|
||||
// lets do the waiting threads there work
|
||||
Thread.Sleep(0);
|
||||
|
||||
QueryPerformanceCounter(out startTime);
|
||||
}
|
||||
|
||||
// Stop the timer
|
||||
public void Stop()
|
||||
{
|
||||
QueryPerformanceCounter(out stopTime);
|
||||
}
|
||||
|
||||
// Returns the duration of the timer (in seconds)
|
||||
public double Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)(stopTime - startTime) / (double)freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class LongestCommonSequenceTests
|
||||
{
|
||||
[Test]
|
||||
public void FunctionalityTest()
|
||||
{
|
||||
//LongestCommonSequence<string> lcs = new LongestCommonSequence<string>();
|
||||
//Debug.WriteLine(new string(lcs.LCS("what do we say", "heya".ToCharArray())));
|
||||
|
||||
List<string> substring = LongestCommonSubstrings.GetLongestSubstring("ABAB", "BABA");
|
||||
Assert.AreEqual(2, substring.Count);
|
||||
Assert.IsTrue(substring.Contains("ABA"));
|
||||
Assert.IsTrue(substring.Contains("BAB"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class Mp3EncoderTests : ProgressCallbackTestBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StreamingVsOutputMp3EncodingTest()
|
||||
{
|
||||
//String inputWav = "44_16_s.wav";
|
||||
String inputWav = "test1.wav";
|
||||
String outputOptionEncodedMp3 = "outputOptionEncodedMp3.mp3";
|
||||
String streamingEncodedMp3 = "streamingEncodedMp3.mp3";
|
||||
|
||||
Mp3EncodingOptions encOpts = new Mp3EncodingOptions();
|
||||
encOpts.Outfile = "-";
|
||||
encOpts.Infile = "-";
|
||||
|
||||
using (FileStream fs = new FileStream(streamingEncodedMp3, FileMode.OpenOrCreate))
|
||||
{
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts, fs))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(inputWav);
|
||||
}
|
||||
}
|
||||
|
||||
encOpts.Outfile = outputOptionEncodedMp3;
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(inputWav);
|
||||
}
|
||||
|
||||
Mp3FileProperties outputOptionProperties = new Mp3FileProperties(outputOptionEncodedMp3);
|
||||
Mp3FileProperties streamingProperties = new Mp3FileProperties(streamingEncodedMp3);
|
||||
Assert.AreEqual(outputOptionProperties.LengthInSeconds, streamingProperties.LengthInSeconds);
|
||||
|
||||
// FilesAreEqual(outputOptionFileInfo, streamingFileInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StreamingVsOutputMp3DecodingTest()
|
||||
{
|
||||
String input = "44_16_s.mp3";
|
||||
String outputOptionDecoded = "outputOptionDecoded.wav";
|
||||
String streamingDecoded = "streamingDecode.wav";
|
||||
|
||||
Mp3EncodingOptions encOpts = new Mp3EncodingOptions();
|
||||
encOpts.Outfile = "-";
|
||||
encOpts.Infile = "-";
|
||||
encOpts.Mp3Input = true;
|
||||
encOpts.DecodeWav = true;
|
||||
|
||||
using (FileStream fileStream = new FileStream(streamingDecoded, FileMode.OpenOrCreate))
|
||||
{
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts, fileStream))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(input);
|
||||
}
|
||||
}
|
||||
|
||||
encOpts.Outfile = outputOptionDecoded;
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(input);
|
||||
}
|
||||
|
||||
FileInfo outputOptionFileInfo = new FileInfo(outputOptionDecoded);
|
||||
FileInfo streamingFileInfo = new FileInfo(streamingDecoded);
|
||||
|
||||
FilesAreEqual(outputOptionFileInfo, streamingFileInfo);
|
||||
}
|
||||
|
||||
private void FilesAreEqual(FileInfo file1, FileInfo file2)
|
||||
{
|
||||
//Assert.AreEqual(file1.Length, file2.Length);
|
||||
|
||||
int filePosition = 0;
|
||||
using (FileStream outputOptionFs = file1.OpenRead())
|
||||
using (StreamReader outputOptionSr = new StreamReader(outputOptionFs))
|
||||
using (FileStream streamingFs = file2.OpenRead())
|
||||
using (StreamReader streamingSr = new StreamReader(streamingFs))
|
||||
{
|
||||
char[] outputOptionBuffer = new char[4096];
|
||||
char[] streamingBuffer = new char[4096];
|
||||
|
||||
while (!outputOptionSr.EndOfStream)
|
||||
{
|
||||
int outputOptionReadLength = outputOptionSr.Read(outputOptionBuffer, 0, outputOptionBuffer.Length);
|
||||
int streamingReadLength = streamingSr.Read(streamingBuffer, 0, streamingBuffer.Length);
|
||||
|
||||
Assert.AreEqual(outputOptionReadLength, streamingReadLength);
|
||||
Assert.AreEqual(outputOptionBuffer, streamingBuffer, "offset : " + filePosition);
|
||||
filePosition += outputOptionBuffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests this instance.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StreamingTest()
|
||||
{
|
||||
String inputWav = "44_16_s.wav";
|
||||
String encodedMp3 = "encodedMp3.mp3";
|
||||
String decodedWav = "decodedWav.wav";
|
||||
String reencodedMp3 = "reencodedMp3.mp3";
|
||||
|
||||
using (FileStream fileStream = new FileStream(encodedMp3, FileMode.OpenOrCreate))
|
||||
{
|
||||
Mp3EncodingOptions encOpts = new Mp3EncodingOptions();
|
||||
encOpts.Outfile = "-";
|
||||
encOpts.Infile = "-";
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts, fileStream))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(inputWav);
|
||||
}
|
||||
}
|
||||
Debug.WriteLine("Finished writing " + encodedMp3);
|
||||
|
||||
Debug.WriteLine("Begin writing " + decodedWav);
|
||||
using (FileStream fileStream = new FileStream(decodedWav, FileMode.OpenOrCreate))
|
||||
{
|
||||
Mp3EncodingOptions wavOpts = new Mp3EncodingOptions();
|
||||
wavOpts.Infile = "-";
|
||||
wavOpts.Outfile = "-";
|
||||
// wavOpts.MonoDownmixing = true;
|
||||
wavOpts.Mp3Input = true;
|
||||
wavOpts.DecodeWav = true;
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(wavOpts, fileStream))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(encodedMp3);
|
||||
}
|
||||
}
|
||||
Debug.WriteLine("Finished writing " + decodedWav);
|
||||
|
||||
using (FileStream fileStream = new FileStream(reencodedMp3, FileMode.OpenOrCreate))
|
||||
{
|
||||
Mp3EncodingOptions encOpts = new Mp3EncodingOptions();
|
||||
encOpts.Outfile = "-";
|
||||
encOpts.Infile = "-";
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts, fileStream))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(decodedWav);
|
||||
}
|
||||
}
|
||||
|
||||
Mp3FileProperties reencodedProperties = new Mp3FileProperties(reencodedMp3);
|
||||
Mp3FileProperties encodedProperties = new Mp3FileProperties(encodedMp3);
|
||||
Assert.AreEqual(encodedProperties.FileLength, reencodedProperties.FileLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
public override void StepTo(int val)
|
||||
{
|
||||
if (val % 10 == 0)
|
||||
base.StepTo(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class Mp3EncodingOptionsTests
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Mp3EncodingOptionsTest()
|
||||
{
|
||||
Mp3EncodingOptions e = new Mp3EncodingOptions();
|
||||
e.ChannelMode = ChannelMode.SingleChannel;
|
||||
e.Infile = "-";
|
||||
string arguments = e.GetCommandLineArguments();
|
||||
Debug.WriteLine(arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for MP3HeaderTests.
|
||||
/// </summary>
|
||||
public class Mp3FilePropertiesTests
|
||||
{
|
||||
|
||||
public void Mp3FileDetailsTest()
|
||||
{
|
||||
string[] files = Directory.GetFiles(".", "*.mp3");
|
||||
List<Mp3FileProperties> properties = new List<Mp3FileProperties>();
|
||||
foreach (string mp3Filename in files)
|
||||
{
|
||||
Debug.WriteLine(mp3Filename);
|
||||
Debug.Indent();
|
||||
|
||||
// bool boolIsMP3 = mp3hdr.ReadMP3Information(mp3Filename);
|
||||
Mp3FileProperties fileDetails = new Mp3FileProperties(mp3Filename);
|
||||
properties.Add(fileDetails);
|
||||
if (fileDetails != null)
|
||||
{
|
||||
Debug.WriteLine(GetMp3FilePropertyReport(fileDetails));
|
||||
}
|
||||
Debug.Unindent();
|
||||
}
|
||||
Mp3FileProperties commonProperties = Mp3FileProperties.GetCommonProperties(properties);
|
||||
Debug.WriteLine(GetMp3FilePropertyReport(commonProperties));
|
||||
}
|
||||
|
||||
private static string GetMp3FilePropertyReport(Mp3FileProperties fileDetails)
|
||||
{
|
||||
StringBuilder report = new StringBuilder();
|
||||
report.AppendLine("Filename: " + fileDetails.Mp3PathAndFilename);
|
||||
report.AppendLine("mFileSize: " + fileDetails.FileSize.ToString());
|
||||
report.AppendLine("mBitRate: " + fileDetails.BitRate.ToString());
|
||||
report.AppendLine("mSampleRateIntegerFrequency:" + fileDetails.SampleRateIntegerFrequency.ToString());
|
||||
report.AppendLine("strMode: " + fileDetails.ChannelMode);
|
||||
report.AppendLine("strLengthFo: " + fileDetails.LengthFormatted);
|
||||
report.AppendLine("mLengthInSeconds: " + fileDetails.LengthInSeconds.ToString());
|
||||
|
||||
report.AppendLine("title: " + fileDetails.Id3Title);
|
||||
report.AppendLine("artist: " + fileDetails.Id3Artist);
|
||||
report.AppendLine("album: " + fileDetails.Id3Album);
|
||||
report.AppendLine("track#: " + fileDetails.Id3TrackNumber);
|
||||
report.AppendLine("genre: " + fileDetails.Id3GenreName);
|
||||
return report.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Media;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class Mp4EncoderTests : ProgressCallbackTestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests Encoding an Mp4 file.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Test()
|
||||
{
|
||||
Mp4EncodingOptions encOpts = new Mp4EncodingOptions();
|
||||
encOpts.OutputFilename = "44_16_s_opts.aac";
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp4Encoder(encOpts))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput("44_16_s.wav");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
public override void StepTo(int val)
|
||||
{
|
||||
if (val%10 == 0)
|
||||
base.StepTo(val);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class Mp4EncodingOptionsTests
|
||||
{
|
||||
[Test]
|
||||
public void Mp4EncodingOptionsTest()
|
||||
{
|
||||
Mp4EncodingOptions e = new Mp4EncodingOptions();
|
||||
e.RawInputChannels = ChannelMode.SingleChannel;
|
||||
string arguments = e.GetCommandLineArguments();
|
||||
Debug.WriteLine(arguments);
|
||||
|
||||
e = new Mp4EncodingOptions();
|
||||
e.OutputFilename = "har";
|
||||
Debug.WriteLine(e.GetCommandLineArguments());
|
||||
|
||||
e.InputFiles = new string[]{"input.txt"};
|
||||
Debug.WriteLine(e.GetCommandLineArguments());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ProcessStreamWrapperTests : ProgressCallbackTestBase
|
||||
{
|
||||
private class StdinToStdoutProcess : ProcessStreamWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the process executable filename, such as "LAME.EXE", "FAAC.EXE", etc.
|
||||
/// </summary>
|
||||
/// <value>The process executable filename.</value>
|
||||
protected override string ProcessExecutableFilename
|
||||
{
|
||||
get { return "StdinToStdout.exe"; }
|
||||
}
|
||||
|
||||
public StdinToStdoutProcess(ProcessArguments encOpt, Stream outputStream)
|
||||
: base(encOpt, outputStream)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ProcessStreamWrapperFunctionalityTest()
|
||||
{
|
||||
string inputString = File.ReadAllText("testText.txt");
|
||||
string writtenString = ""; // string that was written to the process
|
||||
|
||||
Stream inputStream = new MemoryStream();
|
||||
|
||||
StreamWriter sw = new StreamWriter(inputStream, Encoding.Default);
|
||||
{
|
||||
int writeSize = 127;
|
||||
for (int i = 0; i < inputString.Length; i += writeSize)
|
||||
{
|
||||
// select a substring of characters from the input string
|
||||
string substring = inputString.Substring(i, (i + writeSize < inputString.Length) ? writeSize : inputString.Length - i);
|
||||
sw.Write(substring.ToCharArray(), 0, substring.Length);
|
||||
writtenString += substring;
|
||||
}
|
||||
}
|
||||
inputStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
Stream outputStream = new MemoryStream();
|
||||
using (StdinToStdoutProcess s = new StdinToStdoutProcess(new ProcessArguments(), outputStream))
|
||||
{
|
||||
s.ProgressCallback = this;
|
||||
s.ProcessInput(inputStream);
|
||||
}
|
||||
|
||||
outputStream.Seek(0, SeekOrigin.Begin);
|
||||
string outputString;
|
||||
using (StreamReader sr = new StreamReader(outputStream, Encoding.Default))
|
||||
{
|
||||
outputString = sr.ReadToEnd();
|
||||
}
|
||||
Assert.AreEqual(writtenString, outputString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the interface progress callback for testing output purposes
|
||||
/// </summary>
|
||||
public class ProgressCallbackTestBase : IProgressCallback
|
||||
{
|
||||
protected string mPreface = "";
|
||||
|
||||
#region IProgressCallback Members
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to initialize
|
||||
/// the progress callback.
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum.</param>
|
||||
/// <param name="maximum">The maximum.</param>
|
||||
public virtual void Begin(int minimum, int maximum)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("Begin min:{0} max:{1}", minimum, maximum));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to initialize
|
||||
/// the progress callback, without setting the range
|
||||
/// </summary>
|
||||
public virtual void Begin()
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("Begin"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to reset the range in the
|
||||
/// progress callback
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum.</param>
|
||||
/// <param name="maximum">The maximum.</param>
|
||||
public virtual void SetRange(int minimum, int maximum)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("SetRange min:{0} max:{1}", minimum, maximum));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to update the progress text.
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
public virtual void SetText(string text)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("SetText : {0}", text));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
public virtual void StepTo(int val)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("StepTo : {0}", val));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to step the progress meter to a
|
||||
/// particular value.
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
public virtual void Increment(int val)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("Increment : {0}", val));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this property is true, then you should abort work
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is aborting; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public virtual bool IsAborting
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.WriteLine(mPreface + "IsAborting");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to finalize the progress meter
|
||||
/// </summary>
|
||||
public virtual void End()
|
||||
{
|
||||
Debug.WriteLine(mPreface + "End");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using Utility;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TranscodeTest : ProgressCallbackTestBase
|
||||
{
|
||||
static string inputMp3 = "Disc 01 - 04.mp3";
|
||||
string outputAac = inputMp3.Replace(".mp3", ".aac");
|
||||
string outputWav = inputMp3.Replace(".mp3", ".wav");
|
||||
private ReaderProgress mReaderProgress = new ReaderProgress();
|
||||
private WriterProgress mWriterProgress = new WriterProgress();
|
||||
|
||||
private Stream mPipeStream;
|
||||
|
||||
[Test]
|
||||
public void TranscodeSingleThreadTest()
|
||||
{
|
||||
Mp3FileProperties mp3Info = new Mp3FileProperties(inputMp3);
|
||||
Debug.WriteLine(mp3Info);
|
||||
|
||||
mPipeStream = new MemoryStream();
|
||||
|
||||
Mp3ReadThread();
|
||||
if (mPipeStream.CanSeek)
|
||||
mPipeStream.Seek(0, SeekOrigin.Begin);
|
||||
WavWriteThread();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TranscodeMultiThreadTest()
|
||||
{
|
||||
//mPipeStream = new BridgeStream();
|
||||
mPipeStream = new PipeStream();
|
||||
(mPipeStream as PipeStream).BlockLastReadBuffer = true;
|
||||
(mPipeStream as PipeStream).MaxBufferLength = 1 * PipeStream.MB;
|
||||
|
||||
// mPipeStream.MaxBufferLength = 100;
|
||||
|
||||
Thread writeThread = new Thread(new ThreadStart(AacWriteThread));
|
||||
writeThread.Start();
|
||||
|
||||
Thread readThread = new Thread(new ThreadStart(Mp3ReadThread));
|
||||
readThread.Start();
|
||||
|
||||
readThread.Join();
|
||||
(mPipeStream as PipeStream).BlockLastReadBuffer = false;
|
||||
writeThread.Join();
|
||||
}
|
||||
|
||||
|
||||
public void Mp3ReadThread()
|
||||
{
|
||||
//int skip = 3;
|
||||
//int limit = 1;
|
||||
//string directory = @"C:\tmp\venus bak\media\audiobooks\Bret Easton Ellis - Lunar Park";
|
||||
//// string directory = @"C:\tmp\venus bak\media\audiobooks\Clarke, Arthur C. - Space Odyssey 01 - 2001, A Space Odyssey";
|
||||
//// string directory = @"C:\tmp\venus bak\media\audiobooks\Guitar Gym\Part 1 - Alternate Picking (Mp3 And Tab)";
|
||||
//string[] files = Directory.GetFiles(directory);
|
||||
string[] files = new string[]{inputMp3};
|
||||
foreach (string mp3File in files)
|
||||
{
|
||||
//if (skip-- > 0)
|
||||
// continue;
|
||||
//if (limit-- == 0)
|
||||
// break;
|
||||
Debug.WriteLine(mp3File);
|
||||
Mp3FileProperties fp = new Mp3FileProperties(mp3File);
|
||||
Debug.WriteLine(fp.ToString());
|
||||
// Mp3 to wav
|
||||
using (FileStream fileStream = new FileStream(mp3File, FileMode.Open))
|
||||
{
|
||||
Mp3EncodingOptions opts = new Mp3EncodingOptions();
|
||||
opts.Infile = "-";
|
||||
opts.Outfile = "-";
|
||||
// opts.BitRate = BitRate.KBPS_32;
|
||||
// opts.Freeformat = true;
|
||||
opts.Mp3Input = true;
|
||||
opts.DecodeWav = true;
|
||||
// opts.DisableWavHeader = true;
|
||||
Debug.WriteLine("MP3 : " + opts.GetCommandLineArguments());
|
||||
// opts.Freeformat = true;
|
||||
// read from the sr, and write to the memory stream
|
||||
using (Mp3Encoder encoder = new Mp3Encoder(opts, mPipeStream))
|
||||
{
|
||||
encoder.ProgressCallback = mReaderProgress;
|
||||
encoder.ProcessInput(fileStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WavWriteThread()
|
||||
{
|
||||
using (FileStream fs = new FileStream(outputWav, FileMode.OpenOrCreate))
|
||||
using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
|
||||
using (StreamReader sr = new StreamReader(mPipeStream, Encoding.Default))
|
||||
{
|
||||
char[] buffer = new char[1024 * 1024];
|
||||
|
||||
while (!sr.EndOfStream)
|
||||
{
|
||||
int readCount = sr.Read(buffer, 0, buffer.Length);
|
||||
sw.Write(buffer, 0, readCount);
|
||||
mWriterProgress.SetText("Wrote " + buffer.Length);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void AacWriteThread()
|
||||
{
|
||||
Mp4EncodingOptions mp4Opts = new Mp4EncodingOptions();
|
||||
mp4Opts.OutputFilename = outputAac;
|
||||
mp4Opts.RawPCMSwapInputBytes = true;
|
||||
mp4Opts.RawPCMInputMode = true;
|
||||
mp4Opts.RawPCMInputSampleRate = 16;
|
||||
mp4Opts.RawPCMInputSampleSize = SampleRateFrequency.Hz_44100;
|
||||
mp4Opts.RawInputChannels = ChannelMode.Stereo;
|
||||
Debug.WriteLine("AAC : " + mp4Opts.GetCommandLineArguments());
|
||||
|
||||
using (Mp4Encoder encoder = new Mp4Encoder(mp4Opts))
|
||||
{
|
||||
encoder.ProgressCallback = mWriterProgress;
|
||||
encoder.ProcessInput(mPipeStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ReaderProgress : ProgressCallbackTestBase
|
||||
{
|
||||
public ReaderProgress()
|
||||
{
|
||||
mPreface = "Reader: ";
|
||||
}
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
public override void StepTo(int val)
|
||||
{
|
||||
if (val % 10 == 0)
|
||||
{
|
||||
|
||||
base.StepTo(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class WriterProgress : ProgressCallbackTestBase
|
||||
{
|
||||
public WriterProgress()
|
||||
{
|
||||
|
||||
mPreface = "\t\t\t\tWriter: ";
|
||||
}
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
public override void StepTo(int val)
|
||||
{
|
||||
if (val % 10 == 0)
|
||||
{
|
||||
|
||||
base.StepTo(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{73C5A642-71EF-471C-A82D-70899904C495}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>App.ico</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>m3uTool</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>m3uTool</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
|
||||
<Reference Include="PipeStream, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\PipeStream\code\bin\Release\PipeStream.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<Name>System.Drawing</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows.Forms">
|
||||
<Name>System.Windows.Forms</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="App.ico" />
|
||||
<Compile Include="DoNothingProgressCallback.cs" />
|
||||
<Compile Include="Redirect.cs" />
|
||||
<Compile Include="Tests\HiPerfTimer.cs" />
|
||||
<Compile Include="KeyedList.cs" />
|
||||
<Compile Include="LongestCommonSequence.cs" />
|
||||
<Compile Include="ProcessArguments.cs" />
|
||||
<Compile Include="IProgressCallback.cs" />
|
||||
<Compile Include="Mp3Encoder.cs" />
|
||||
<Compile Include="Mp3EncodingOptions.cs" />
|
||||
<Compile Include="Mp3FileProperties.cs" />
|
||||
<Compile Include="ProcessStreamWrapper.cs" />
|
||||
<Compile Include="Mp4Encoder.cs" />
|
||||
<Compile Include="Mp4EncodingOptions.cs" />
|
||||
<Compile Include="AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="M3uCreate.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="M3uMakeByDirectory.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="M3uToAac.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="M3uToAac.Designer.cs">
|
||||
<DependentUpon>M3uToAac.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Mp3ToAacBatch.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Mp3ToAacBatch.Designer.cs">
|
||||
<DependentUpon>Mp3ToAacBatch.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Tests\CreateM3uTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Tests\LongestCommonSequenceTests.cs" />
|
||||
<Compile Include="Tests\Mp3EncoderTests.cs" />
|
||||
<Compile Include="Tests\Mp3EncodingOptionsTests.cs" />
|
||||
<Compile Include="Tests\Mp3FilePropertiesTests.cs" />
|
||||
<Compile Include="Tests\Mp4EncoderTests.cs" />
|
||||
<Compile Include="Tests\Mp4EncodingOptionsTests.cs" />
|
||||
<Compile Include="Tests\ProgressCallbackTestBase.cs" />
|
||||
<Compile Include="Tests\ProcessStreamWrapperTests.cs" />
|
||||
<Compile Include="Tests\TranscodeTest.cs" />
|
||||
<EmbeddedResource Include="M3uMakeByDirectory.resx">
|
||||
<DependentUpon>M3uMakeByDirectory.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="M3uToAac.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>M3uToAac.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Mp3ToAacBatch.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>Mp3ToAacBatch.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>copy /D /Y "$(ProjectDir)Tests\"*.mp3 "$(TargetDir)"
|
||||
copy /D /Y "$(ProjectDir)Tests\"*.wav "$(TargetDir)"
|
||||
copy /D /Y "$(ProjectDir)Tests\"*.exe "$(TargetDir)"
|
||||
copy /D /Y "$(ProjectDir)Tests\"*.txt "$(TargetDir)"</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,25 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "m3uTool", "m3uTool.csproj", "{73C5A642-71EF-471C-A82D-70899904C495}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StdinToStdout", "..\StdinToStdout\StdinToStdout.csproj", "{94C7033C-C8A8-4104-95FE-0D11122080E2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{73C5A642-71EF-471C-A82D-70899904C495}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{73C5A642-71EF-471C-A82D-70899904C495}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{73C5A642-71EF-471C-A82D-70899904C495}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{73C5A642-71EF-471C-A82D-70899904C495}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{94C7033C-C8A8-4104-95FE-0D11122080E2}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{94C7033C-C8A8-4104-95FE-0D11122080E2}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{94C7033C-C8A8-4104-95FE-0D11122080E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{94C7033C-C8A8-4104-95FE-0D11122080E2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Reference in New Issue
Block a user