Replicate Wave File Using Naudio - Copy / Add Recent Available Bytes

I have an active wave recording wave-file.wavthat happens to a folder Source. I need to copy this file to a folder Destinationwith a new name wave-file-copy.wav.

Recording and replication must occur in parallel. I completed a scheduled task that will run every 10 minutes and copy the file Sourceto Destination.

private static void CopyWaveFile(string destinationFile, string sourceFile){
        using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
            using (var reader = new WaveFileReader(fs)){
                using (var writer = new WaveFileWriter(destinationFile, reader.WaveFormat)){
                    reader.Position = 0;
                    var endPos = (int)reader.Length;
                    var buffer = new byte[1024];
                    while (reader.Position < endPos){
                        var bytesRequired = (int)(endPos - reader.Position);
                        if (bytesRequired <= 0) continue;
                        var bytesToRead = Math.Min(bytesRequired, buffer.Length);
                        var bytesRead = reader.Read(buffer, 0, bytesToRead);
                        if (bytesRead > 0){
                            writer.Write(buffer, 0, bytesRead);
                        }
                    }
                }
            }
        }
    }

The copy operation works fine, although the source file is constantly updated.

The time taken for the copy operation increases in linear time because I copy the entire file every time.

I am trying to implement a new function ConcatenateWavFiles()that should update the contents of the target file, with the last available bytes of the source record.

- , , :

  • .
  • length reader.Position waveReader
  • , .

    public static void ConcatenateWavFiles(string destinationFile, string sourceFile){  
    
        WaveFileWriter waveFileWriter = null;
        var sourceReadOffset = GetWaveFileSize(destinationFile);
    
        try{
            using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var reader = new WaveFileReader(fs))
                {
                    waveFileWriter = new WaveFileWriter(destinationFile, reader.WaveFormat);
                    if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat)){
                        throw new InvalidOperationException(
                            "Can't append WAV Files that don't share the same format");
                    }
    
                    var startPos = sourceReadOffset - sourceReadOffset % reader.WaveFormat.BlockAlign;
                    var endPos = (int) reader.Length;
                    reader.Position = startPos;
                    var bytesRequired = (int)(endPos - reader.Position);
                    var buffer = new byte[bytesRequired];
                    if (bytesRequired > 0)
                    {
                        var bytesToRead = Math.Min(bytesRequired, buffer.Length);
                        var bytesRead = reader.Read(buffer, 0, bytesToRead);
    
                        if (bytesRead > 0)
                        {
                            waveFileWriter.Write(buffer, startPos, bytesRead);
                        }
                    }
                }
            }
        }
        finally{
            if (waveFileWriter != null){
                waveFileWriter.Dispose();
            }
        }
    }
    

.

?

, ?

- Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.

+4
2

NAudio.

# MemoryStreams FileStreams.

  • , .
  • ( ) .
  • Wave, . ( , .
  • .

    public void ReplicateFile(string destinationFile, string sourceFile){
    
        if (!Directory.Exists(GetRoutePathFromFile(sourceFile)))
            return;           
    
        if (!File.Exists(sourceFile))                
            return;           
    
        if (Directory.Exists(GetRoutePathFromFile(destinationFile))){
            if (File.Exists(destinationFile)){                                         
                UpdateLatestWaveFileContent(destinationFile, sourceFile);
            }else{                 
                CopyWaveFile(destinationFile, sourceFile);
            }
        }else{                        
            Directory.CreateDirectory(GetRoutePathFromFile(destinationFile));
            CopyWaveFile(destinationFile, sourceFile);
        }
    }
    
    
    
    
    private static string GetRoutePathFromFile(string file){
        var rootPath = Directory.GetParent(file);
        return rootPath.FullName;
    }
    
    
    
    
    
    private static void CopyWaveFile(string destination, string source){
        var sourceMemoryStream = new MemoryStream();
        using (var fs = File.Open(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
            fs.CopyTo(sourceMemoryStream);
        }            
        using (var fs = new FileStream(destination, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite)){
            sourceMemoryStream.WriteTo(fs);               
        }
    }
    
    
    
    
    private static void UpdateLatestWaveFileContent(string destinationFile, string sourceFile){
        var sourceMemoryStream = new MemoryStream();
        long offset = 0;
    
        using (var fs = File.Open(destinationFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
            offset = fs.Length;
        }
    
        using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
            fs.CopyTo(sourceMemoryStream);
        }
    
        var length = sourceMemoryStream.Length - offset;            
    
        var buffer = sourceMemoryStream.GetBuffer();
        using (var fs = new FileStream(destinationFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)){                
            fs.Write(buffer, (int)offset, (int)length);
        }
    
    
        var bytes = new byte[45];
    
        for (var i = 0; i < 45; i++){
            bytes[i] = buffer[i];
        }
    
        ModifyHeaderDataLength(destinationFile, 0, bytes);
    }
    
    
    
    private static void ModifyHeaderDataLength(string filename, int position, byte[] data){
        using (Stream stream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
        {
            stream.Position = position;
            stream.Write(data, 0, data.Length);
        }
    }
    
+3

Wav .

, .

0

Source: https://habr.com/ru/post/1628274/


All Articles