Opis forum
mamy wave'a, który ma następujący schemat: cisza-słowo-cisza-słowo-cisza...
mamy wyodrębnić słowa i zapisać je do oddzielnych plików
jak wiadomo cisza ciszą nie będzie, więc moja koncepcja:
znamy próbkowanie, przejeżdżamy przez plik i sprawdzamy, czy uśredniona wartość sygnału w przedziale odpowiadającym za np. pół sekundy jest wyższa niż w jakimś wcześniejszym przedziale. w ten sposób liniowo możemy wyodrębnić słowa.
stworzyć jakiś pliczek wave i stestować działanie
priorytet mniej pilny.
kto robi? sky?
Offline
macie tutaj zrobione w formie ;d testowac kurwa!
http://frog.sphere-research.com/~lsentkiewicz/Wavy.exe
zrobilem i dziala w sumie fajnie i dobrze ;d
robimy
new WaveCut(sciezka_do_pliku_wav);
i w tym samym katologu mamy pocietego wave'a
public class WaveCut
{
private UInt32
ChunkSize, Subchunk1Size, SampleRate, ByteRate, DataSize;
private UInt16
Format, NumChannels, BlockAlign, BitsPerSample;
private Int32
silentSampleRate, averageSample, dataSize;
private Byte[]
Data, Header = new Byte[40];
private Int16[] data;
private List<Byte[]> CutedAudio = new List<Byte[]>();
private Stream input;
private Double silentTime = 0.35;
private List<part> parts = new List<part>();
private class part
{
private bool isSilent;
private int begin, end, length;
public part(int begin, int end, bool isSilent)
{
this.begin = begin;
this.end = end;
this.isSilent = isSilent;
length = end - begin;
}
public bool IsSilent
{
get { return isSilent; }
set { isSilent = value; }
}
public int Begin
{
get { return begin; }
set { begin = value; length = end - begin; }
}
public int End
{
get { return end; }
set { end = value; length = end - begin; }
}
public int Length
{
get { return length; }
set { length = value; }
}
}
private void init(Stream input)
{
this.input = input;
input.Read(Header, 0, 40);
input.Seek(4, SeekOrigin.Begin);
ChunkSize = nextUInt32;
input.Seek(16, SeekOrigin.Begin);
Subchunk1Size = nextUInt32;
Format = nextUInt16;
NumChannels = nextUInt16;
SampleRate = nextUInt32;
ByteRate = nextUInt32;
BlockAlign = nextUInt16;
BitsPerSample = nextUInt16;
input.Seek(40, SeekOrigin.Begin);
DataSize = nextUInt32;
Data = new Byte[DataSize];
input.Read(Data, 0, (int)DataSize);
input.Close();
}
private UInt16 nextUInt16
{
get
{
return (UInt16)((input.ReadByte()) | (input.ReadByte() << 8));
}
}
private UInt32 nextUInt32
{
get
{
return (UInt32)(input.ReadByte() | (input.ReadByte() << 8) | (input.ReadByte() << 16) | (input.ReadByte() << 24));
}
}
private void doit()
{
dataSize = (Int32)DataSize / 2;
data = new Int16[dataSize];
silentSampleRate = (Int32)(silentTime * SampleRate);
for (int i = 0; i < DataSize; i += 2)
{
UInt16 n = (UInt16)((Data[i + 1] << 8) | Data[i]);
if (n >> 15 == 1)
{
n ^= 0xffff;
}
data[i / 2] = (Int16)n;
averageSample += n;
}
averageSample /= dataSize / 2;
for (int pos = 0, start = 0; pos < dataSize; start = pos)
{
bool isSilent = data[start] <= averageSample;
while (pos < dataSize &&
data[pos] <= averageSample == isSilent)
{
pos++;
}
parts.Add(new part(start, pos, isSilent));
}
for (int i = parts.Count - 1; i > 0; i--)
{
if (parts[i].Length < 100)
{
parts[i - 1].End = parts[i].End;
parts.Remove(parts[i]);
}
}
for (int i = parts.Count - 2; i >= 0; i--)
{
if (parts[i].IsSilent == parts[i + 1].IsSilent)
{
parts[i].End = parts[i + 1].End;
parts.Remove(parts[i + 1]);
}
}
List<int> silentsPos = new List<int>();
for (int i = 0; i < parts.Count; i++)
{
if (parts[i].IsSilent && parts[i].Length > silentSampleRate)
{
silentsPos.Add(i);
}
}
for (int i = 0; i < silentsPos.Count - 1; i++)
{
int left = parts[silentsPos[i]].End * 2 - (int)SampleRate / 2, right = parts[silentsPos[i + 1]].Begin * 2 + (int)SampleRate / 2;
int len = right - left;
if (len < 10000 + (int)SampleRate) continue;
Byte[] tmp = new Byte[len];
CutedAudio.Add(tmp);
Array.Copy(Data, left, CutedAudio[CutedAudio.Count - 1], 0, len);
}
}
private void convert(string path)
{
int nr = 0;
foreach (Byte[] Data in CutedAudio)
{
nr++;
FileStream output = new FileStream(path + "_Part_" + nr + ".wav", FileMode.Create);
output.Write(Header, 0, 40);
output.WriteByte((Byte)(Data.Length & 0x000000ff));
output.WriteByte((Byte)((Data.Length & 0x0000ff00) >> 2));
output.Write(Data, 0, Data.Length);
}
}
public WaveCut(string wavePath)
{
init(new FileStream(wavePath, FileMode.Open, FileAccess.Read));
doit();
wavePath = wavePath.Substring(0, wavePath.Length - 4);
convert(wavePath);
}
}Ostatnio edytowany przez Sky (2009-09-05 19:43:20)
Offline