1

I'm trying to convert .sd9 files to .wav files in C#, these files are basically .wav files with unessecary headers (used in certain games).

I found some NodeJS code online to do so, this code works fine:

   var snd_buf = fs.readFileSync(item);

    if (snd_buf.slice(0x00, 0x03).toString() != "SD9") {
        console.log("[-] '" + path.basename(item) + "' is not SD9 file.");
        continue;
    }

    var wav_buf = snd_buf.slice(0x20, snd_buf.length);

    if (sd9_file_list.length > 1) {
        if (!fs.existsSync(output_path)) {
            fs.mkdirSync(output_path);
        }

        output_path += "/" + path.basename(item, ".sd9") + ".wav";
    }

    output_path = path.normalize(output_path);

    fs.writeFileSync(output_path, wav_buf);

item: Full path to the file

Now I'm trying to 'translate' this C# without any luck:

string[] files = Directory.GetFiles(fbd.SelectedPath, "*.sd9", SearchOption.AllDirectories);

foreach (string file in files)
{
UTF8Encoding nobom = new UTF8Encoding(false);

string raw_buffer = File.ReadAllText(file, nobom);

string wave_buffer = "";

if (raw_buffer.Substring(0x00, 0x03) == "SD9")
{
    wave_buffer = raw_buffer.Substring(0x20);
    MessageBox.Show(wave_buffer);
}

if (File.Exists(fbdd.SelectedPath + @"\" + Path.GetFileNameWithoutExtension(file) + ".wav")) { File.Delete(fbdd.SelectedPath + @"\" + Path.GetFileNameWithoutExtension(file) + ".wav");  }

BinaryWriter sw = new BinaryWriter(new FileStream(fbdd.SelectedPath + @"\" + Path.GetFileNameWithoutExtension(file) + ".wav", FileMode.CreateNew));
sw.Write(wave_buffer);
sw.Flush();
sw.Close();
}

Either the way of writing or reading seems to add unnecessary headers / malformed bytes or whatever to make the file unreadable, for example, a correctly converted file with the NodeJS script is 91KB while my script outputs a corrupted file of 140KB.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Arena
  • 360
  • 3
  • 10
  • You are reading your file as a string. It is a binary file. You need to deal in bytes, not characters and strings. – Matt Houser May 14 '15 at 17:42
  • Okay, I've tried using File.ReadAllBytes but then my problem is, how do I properly 'cut away'/remove the unnecessary headers from the byte array like I am trying to do with Substring – Arena May 14 '15 at 17:56

1 Answers1

0

Your problem is that you are reading in your SD9 file as a string. You're then using string functions to slice the file apart. Instead, you want to read your file as byte[].

  1. Use File.ReadAllBytes() to read your file as byte[].
  2. Use this trick to "splice" your byte array: Getting a sub-array from an existing array
  3. Use System.Text.Encoding.ASCII.GetString() to convert byte[] to string for the "SD9" header comparison.
  4. Use File.WriteAllBytes() to write your new file.
Community
  • 1
  • 1
Matt Houser
  • 33,983
  • 6
  • 70
  • 88
  • Yay, after hours of puzzling finally a solution that works, thanks Matt! :D (And Marc ofcourse; The person who answered the sub-array thread) – Arena May 14 '15 at 22:14