static void ExportAllLow(string filename, uint voca_baseaddress, bool isNest)
        {
            voca_baseaddress = U.toOffset(voca_baseaddress);
            if (!U.isSafetyOffset(voca_baseaddress))
            {
                return;
            }

            string dir      = Path.GetDirectoryName(filename);
            string basename = Path.GetFileNameWithoutExtension(filename);

            //楽器リスト本体
            InputFormRef InputFormRef = Init(null);

            InputFormRef.ReInit(voca_baseaddress);

            List <string> lines = new List <string>();

            uint voca_endaddress = voca_baseaddress + ((InputFormRef.DataCount + 1) * InputFormRef.BlockSize);
            uint addr            = voca_baseaddress;

            for (int i = 0; i < InputFormRef.DataCount; i++, addr += InputFormRef.BlockSize)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(U.ToHexString(Program.ROM.u8(addr + 0))); sb.Append("\t");
                sb.Append(U.ToHexString(Program.ROM.u8(addr + 1))); sb.Append("\t");
                sb.Append(U.ToHexString(Program.ROM.u8(addr + 2))); sb.Append("\t");
                sb.Append(U.ToHexString(Program.ROM.u8(addr + 3))); sb.Append("\t");

                uint type = Program.ROM.u8(addr);
                if (type == 0x00 ||
                    type == 0x08 ||
                    type == 0x10 ||
                    type == 0x18
                    )
                {//directsound waveデータ.
                    uint songdata_addr = Program.ROM.p32(addr + 4);
                    if (!U.isSafetyOffset(songdata_addr))
                    {
                        continue;
                    }
                    uint sample_length = Program.ROM.u32(songdata_addr + 12);
                    if (!U.isSafetyLength(songdata_addr + 12 + 4, sample_length))
                    {
                        continue;
                    }
                    if (!SongUtil.IsDirectSoundData(Program.ROM.Data, songdata_addr))
                    {//壊れたデータ
                        continue;
                    }

                    string waveFilename = basename + U.To0xHexString(i) + ".DirectSound.bin";
                    byte[] bin          = Program.ROM.getBinaryData(songdata_addr, 12 + 4 + sample_length);
                    U.WriteAllBytes(Path.Combine(dir, waveFilename), bin);

                    sb.Append(waveFilename); sb.Append("\t");
                }
                else if (type == 0x03 ||
                         type == 0x0B
                         )
                {//波形データ
                    uint songdata_addr = Program.ROM.p32(addr + 4);
                    if (!U.isSafetyOffset(songdata_addr))
                    {
                        continue;
                    }

                    byte[] bin          = Program.ROM.getBinaryData(songdata_addr, 16);
                    string waveFilename = basename + U.To0xHexString(i) + ".Wave.bin";
                    U.WriteAllBytes(Path.Combine(dir, waveFilename), bin);

                    sb.Append(waveFilename); sb.Append("\t");
                }
                else if (type == 0x80)
                {//ドラム
                    uint drum_voices = Program.ROM.p32(addr + 4);
                    if (!U.isSafetyOffset(drum_voices))
                    {
                        continue;
                    }

                    if (drum_voices == voca_baseaddress)
                    {
                        sb.Append("@SELF+0"); sb.Append("\t");
                    }
                    else if (isNest)
                    {
                        if (drum_voices >= voca_baseaddress && drum_voices < voca_endaddress)
                        {
                            sb.Append("@SELF+" + U.ToHexString(drum_voices - voca_baseaddress)); sb.Append("\t");
                        }
                        else
                        {
                            sb.Append("@BROKENDATA"); sb.Append("\t");
                        }
                    }
                    else
                    {
                        string drumFilename = basename + U.To0xHexString(i) + ".Drum.instrument";
                        ExportAllLow(Path.Combine(dir, drumFilename), drum_voices, true);
                        sb.Append(drumFilename); sb.Append("\t");
                    }
                }
                else if (type == 0x40)
                {//マルチサンプル
                    uint multisample_voices = Program.ROM.p32(addr + 4);
                    uint sample_location    = Program.ROM.p32(addr + 8);
                    if (!U.isSafetyOffset(multisample_voices))
                    {
                        continue;
                    }
                    if (!U.isSafetyOffset(sample_location))
                    {
                        continue;
                    }

                    if (multisample_voices == voca_baseaddress)
                    {
                        sb.Append("@SELF+0"); sb.Append("\t");
                    }
                    else if (isNest)
                    {
                        if (multisample_voices >= voca_baseaddress && multisample_voices < voca_endaddress)
                        {
                            sb.Append("@SELF+" + U.ToHexString(multisample_voices - voca_baseaddress)); sb.Append("\t");
                        }
                        else
                        {
                            sb.Append("@BROKENDATA"); sb.Append("\t");
                        }
                    }
                    else
                    {//自己参照以外を記録します
                        string multiFilename = basename + U.To0xHexString(i) + ".Multi.instrument";
                        ExportAllLow(Path.Combine(dir, multiFilename), multisample_voices, true);
                        sb.Append(multiFilename); sb.Append("\t");
                    }

                    byte[] bin          = Program.ROM.getBinaryData(sample_location, 128);
                    string waveFilename = basename + U.To0xHexString(i) + ".Multi.keys.bin";
                    U.WriteAllBytes(Path.Combine(dir, waveFilename), bin);

                    sb.Append(waveFilename); sb.Append("\t");
                }
                else
                {
                    sb.Append(U.ToHexString(Program.ROM.u8(addr + 4))); sb.Append("\t");
                    sb.Append(U.ToHexString(Program.ROM.u8(addr + 5))); sb.Append("\t");
                    sb.Append(U.ToHexString(Program.ROM.u8(addr + 6))); sb.Append("\t");
                    sb.Append(U.ToHexString(Program.ROM.u8(addr + 7))); sb.Append("\t");
                }

                if (type != 0x40)
                {//マルチサンプル以外は、最後の4バイトはデータです
                    sb.Append(U.ToHexString(Program.ROM.u8(addr + 8))); sb.Append("\t");
                    sb.Append(U.ToHexString(Program.ROM.u8(addr + 9))); sb.Append("\t");
                    sb.Append(U.ToHexString(Program.ROM.u8(addr + 10))); sb.Append("\t");
                    sb.Append(U.ToHexString(Program.ROM.u8(addr + 11)));
                }

                U.AddrResult ar = InputFormRef.LoopCallback(i, addr);
                if (!ar.isNULL())
                {
                    sb.Append("\t//");
                    sb.Append(ar.name);
                }

                lines.Add(sb.ToString());
            }
            File.WriteAllLines(filename, lines);
        }
        public static void RecycleOldInstrument(ref List <Address> recycle, string basename, uint voca_basepointer)
        {
            if (!U.isSafetyOffset(voca_basepointer))
            {
                return;
            }

            uint voca_baseaddress = Program.ROM.u32(voca_basepointer);

            if (!U.isPointer(voca_baseaddress))
            {
                return;
            }
            voca_baseaddress = U.toOffset(voca_baseaddress);
            if (!U.isSafetyOffset(voca_baseaddress))
            {
                return;
            }

            //既に記録しているならば無視.
            for (int i = 0; i < recycle.Count; i++)
            {
                if (recycle[i].Addr == voca_baseaddress)
                {
                    return;
                }
            }

            //楽器リスト本体
            InputFormRef InputFormRef = Init(null);

            InputFormRef.ReInitPointer(voca_basepointer);
            FEBuilderGBA.Address.AddAddress(recycle
                                            , InputFormRef
                                            , basename
                                            , new uint[] { 4, 8 }
                                            );

            uint voca_endaddress = voca_baseaddress + ((InputFormRef.DataCount + 1) * InputFormRef.BlockSize);
            uint addr            = voca_baseaddress;

            for (int i = 0; i < InputFormRef.DataCount; i++, addr += InputFormRef.BlockSize)
            {
                uint type = Program.ROM.u8(addr);
                if (type == 0x00 ||
                    type == 0x08 ||
                    type == 0x10 ||
                    type == 0x18
                    )
                {//directsound waveデータ.
                    uint songdata_addr = Program.ROM.p32(addr + 4);
                    if (!U.isSafetyOffset(songdata_addr))
                    {
                        continue;
                    }
                    uint sample_length = Program.ROM.u32(songdata_addr + 12);
                    if (!U.isSafetyLength(songdata_addr + 12 + 4, sample_length))
                    {//壊れたデータ 長さが取れない
                        FEBuilderGBA.Address.AddPointer(recycle
                                                        , addr + 4
                                                        , 0
                                                        , basename + U.To0xHexString(i) + "DIRECTSOUND(BROKEN)"
                                                        , FEBuilderGBA.Address.DataTypeEnum.SONGINSTDIRECTSOUND);
                        continue;
                    }
                    if (!SongUtil.IsDirectSoundData(Program.ROM.Data, songdata_addr))
                    {//壊れたデータ
                        FEBuilderGBA.Address.AddPointer(recycle
                                                        , addr + 4
                                                        , 0
                                                        , basename + U.To0xHexString(i) + "DIRECTSOUND(BROKEN)"
                                                        , FEBuilderGBA.Address.DataTypeEnum.SONGINSTDIRECTSOUND);
                        continue;
                    }

                    FEBuilderGBA.Address.AddPointer(recycle
                                                    , addr + 4
                                                    , 12 + 4 + sample_length
                                                    , basename + U.To0xHexString(i) + "DIRECTSOUND"
                                                    , FEBuilderGBA.Address.DataTypeEnum.SONGINSTDIRECTSOUND);
                }
                else if (type == 0x03 ||
                         type == 0x0B
                         )
                {//波形データ
                    uint songdata_addr = Program.ROM.p32(addr + 4);
                    if (!U.isSafetyOffset(songdata_addr))
                    {
                        continue;
                    }
                    FEBuilderGBA.Address.AddPointer(recycle
                                                    , addr + 4
                                                    , 16
                                                    , basename + U.To0xHexString(i) + "WAVE"
                                                    , FEBuilderGBA.Address.DataTypeEnum.SONGINSTWAVE);
                }
                else if (type == 0x80)
                {//ドラム
                    uint drum_voices = Program.ROM.p32(addr + 4);
                    if (!U.isSafetyOffset(drum_voices))
                    {
                        continue;
                    }

                    RecycleOldInstrument(ref recycle
                                         , basename + U.To0xHexString(i) + "DRUM "
                                         , addr + 4);
                }
                else if (type == 0x40)
                {//マルチサンプル
                    uint multisample_voices = Program.ROM.p32(addr + 4);
                    uint sample_location    = Program.ROM.p32(addr + 8);
                    if (!U.isSafetyOffset(multisample_voices))
                    {
                        continue;
                    }
                    if (!U.isSafetyOffset(sample_location))
                    {
                        continue;
                    }

                    RecycleOldInstrument(ref recycle
                                         , basename + U.To0xHexString(i) + "MULTI "
                                         , addr + 4);

                    FEBuilderGBA.Address.AddPointer(recycle
                                                    , addr + 8
                                                    , 128
                                                    , basename + U.To0xHexString(i) + "MULTI2"
                                                    , FEBuilderGBA.Address.DataTypeEnum.BIN);
                }
            }
        }