Sie sind hier: flac format
Zurück zu: File Formats
Allgemein:
Vorlesungen
Labore
Sinnvolle Programme
Lineare Regression
GUI-Entwurfsarbeit
Single-Format
Design Pattern-Termine
Observer1
Bsp2
Json-Array
Json-Dialogelemente
Webtechnologien
The flac format is used to play with a modern Diagital Analog Converter (DAC).
It is compressed but without any lost information, such as a mp3 file.
The sampling rate a to 192 kHz and a bitrate to 24 Bit.
I hear music with flacs, dsf and wav file with a T&A DAC 8 DSD.
But the Media Player I choose want to regist all files.
For me, that was uncomfortable, so I wrote MY own audio player.
Properties:
- There is a tree list for the folder of the solngs
- One can choose one or many folder to read the songs.
- The are read recursivly.
- The program can stop, start, and play behind and forward to the song.
- The program can change the volume ot the music.
- The program show the title, samplingrate and bitrate from the songs.
Therefore I have to read the mp3, wav and flac file, to read the informations.
Description_Audioplayer.pdf
AudioPlayer.exe
AudioPlayer.zip
AudioPlayer-Source.zip
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Runtime.Serialization.Formatters.Binary; namespace AudioPlayer.Tools { public class Flac { public String filename = ""; public String album = ""; public String artist = ""; public String title = ""; public int samplerate = 0; public int minutes = 0; public int seconds = 0; public int bitcount = 0; public Flac(String filename) { this.filename = filename; } public bool readSamplerate() { FileStream fin = new FileStream(this.filename, FileMode.Open, FileAccess.Read); BinaryReader bin = new BinaryReader(fin); // fLaC byte[] headerSoll = { 0x66, 0x4C, 0x61, 0x43 }; byte[] header = new byte[headerSoll.Length]; header = bin.ReadBytes(header.Length); for (int i = 0; i < headerSoll.Length; i++) { if (headerSoll[i] != header[i]) { Basis.ErrorMsg("Error, the audiofile is not a FLAC-File\r\n" + filename, "Error"); bin.Close(); fin.Close(); return false; } } // samplerate fin.Seek(0x12,SeekOrigin.Begin); // jump to the first byte of the sampleRate byte[] samplerates = new byte[3]; //dummy1 = bin.ReadBytes(dummy1.Length); samplerates = bin.ReadBytes(samplerates.Length); // adr: 12=byte[0], 13=byte[1], 14=byte[2] Bits: 12+13+ highbyte(14) int b0 = samplerates[0]; int b1 = samplerates[1]; int b2 = samplerates[2]; samplerate = (b0 << 12) | (b1 << 4) | (b2 >> 4); // 192 kHz //fin.Seek(0x12, SeekOrigin.Begin); // jump to the first byte of the sampleRate byte[] samplescount = new byte[5]; samplescount = bin.ReadBytes(samplescount.Length); // 0x15 bis 0x19 von 0x15 nur die unteren bits int sc0 = samplescount[0] & 0xF; int sc1 = samplescount[1]; int sc2 = samplescount[2]; int sc3 = samplescount[3]; int sc4 = samplescount[4]; long scount = (sc0 << 32) | (sc1 << 24) | (sc2 << 16) | (sc3 << 8) | sc4; long seconds = (long) (scount / samplerate); this.minutes = (int)(seconds / 60.0); this.seconds = (int)(seconds % 60); byte[] channels = new byte[3]; channels = bin.ReadBytes(channels.Length); // 0x15 bis 0x19 von 0x15 nur die unteren bits int bitcount0 = samplescount[0] >> 4; // F int bitcount1 = samplerates[2] & 0xF; // 2 bitcount = (bitcount1<<4) | bitcount0; // es sind nur 5 Bit zuständig bitcount = bitcount >> 3; /* https://xiph.org/flac/format.html#def_STREAMINFO 000 : get from STREAMINFO metadata block 001 : 8 bits per sample 010 : 12 bits per sample 011 : reserved 100 : 16 bits per sample 101 : 20 bits per sample 110 : 24 bits per sample 111 : reserved */ if (bitcount==5) { bitcount = 16; } else if (bitcount == 6) { bitcount = 24; } else { Basis.ErrorMsg("Error to get the bits/sample\r\nPlease send an email to mwilhelm@hs-harz.de", "Error"); bitcount = -1; } bin.Close(); fin.Close(); return true; } /* 000 : get from STREAMINFO metadata block 001 : 8 bits per sample 010 : 12 bits per sample 011 : reserved 100 : 16 bits per sample 101 : 20 bits per sample 110 : 24 bits per sample 111 : reserved * */ public bool readTexte() { FileStream fin = new FileStream(this.filename, FileMode.Open, FileAccess.Read); BinaryReader bin = new BinaryReader(fin); // fLaC byte[] headerSoll = { 0x66, 0x4C, 0x61, 0x43 }; byte[] header = new byte[headerSoll.Length]; header = bin.ReadBytes(header.Length); for (int i1 = 0; i1 < headerSoll.Length; i1++) { if (headerSoll[i1] != header[i1]) { Basis.ErrorMsg("Error, the audiofile is not a FLAC-File\r\n" + filename, "Error"); bin.Close(); fin.Close(); return false; } } fin.Seek(0, SeekOrigin.Begin); byte[] bytes = new byte[10000]; bytes = bin.ReadBytes(bytes.Length); // suche reference, dann ALBUMARTIST, ALBUM TITLE title String searchItem = "reference"; bool reference = false; int i = 0; byte b = 0; int positionReference = searchString(bytes, searchItem); if (positionReference == -1) { int p1 = searchString(bytes, "ALBUM="); int p2 = searchString(bytes, "TITLE="); int p3 = searchString(bytes, "title="); int p4 = searchString(bytes, "ARTIST="); if (p1 > 0 && p4 > 0 && (p2 > 0 || p3 > 0)) { // nun gibt es doch einträge bin.Close(); fin.Close(); // nun weiter siehe unten } else { Basis.ErrorMsg("Error, the audiofile has not a reference-Block\r\n" + filename, "Error"); bin.Close(); fin.Close(); return false; } } else { positionReference += searchItem.Length; // Position auf das Byte nach der reference setzen fin.Seek(positionReference, SeekOrigin.Begin); bytes = bin.ReadBytes(bytes.Length); // nun nach reference lesen bin.Close(); fin.Close(); } album = "Please send an email to me!"; artist = "Please send an email to me!"; title = "Please send an email to me!"; searchItem = "ALBUM="; int position = searchString(bytes, searchItem); if (position == -1) { searchItem = "Album="; position = searchString(bytes, searchItem); if (position == -1) { searchItem = "album="; position = searchString(bytes, searchItem); if (position == -1) { Basis.ErrorMsg("Error, the audiofile has no ALBUM-Text\r\n" + filename, "Error"); return false; } } } position += searchItem.Length; album = searchTextUntilZero(bytes, position); // ----------------------------------------- searchItem = "TITLE="; position = searchString(bytes, searchItem); if (position==-1) { searchItem = "Title="; position = searchString(bytes, searchItem); if ((position == -1) ) { searchItem = "title="; position = searchString(bytes, searchItem); if ((position == -1)) { Basis.ErrorMsg("Error, the audiofile has no TITLE-Text\r\n" + filename, "Error"); return false; } } } if (position > 0) { title = searchTextUntilZero(bytes, position); } searchItem = "ARTIST="; position = searchString(bytes, searchItem); if (position == -1) { searchItem = "Artist="; position = searchString(bytes, searchItem); if ((position == -1)) { searchItem = "artist="; position = searchString(bytes, searchItem); if ((position == -1)) { Basis.ErrorMsg("Error, the audiofile has no Artist-Text\r\n" + filename, "Error"); return false; } } } if (position > 0) { artist = searchTextUntilZero(bytes, position); } return true; } // readTexte private String searchTextUntilZero(byte[] bytes, int position) { StringBuilder sb = new StringBuilder(); for (int i=position; i=32) { if (bytes[i] == 0xC3 && bytes[i+1] == 0xBC) { sb.Append("ü"); i++; } else { sb.Append((char)bytes[i]); } } } } return sb.ToString(); } // searchTextUntilZero private int searchString(byte[] bytes, String searchItem) { int position = -1; byte[] searchItemBytes = new byte[searchItem.Length]; // Unicode !! for (int i = 0; i < searchItem.Length; i++) { searchItemBytes[i] = (byte)searchItem[i]; } for(int i =0; i< bytes.Length;i++) { if (bytes[i] == searchItemBytes[0]) { // prüfe die Länge bool okay = true; for (int j = 0; j < searchItem.Length; j++) { if (i + j < bytes.Length) { if (bytes[i + j] != searchItemBytes[j]) { // error bei Paul Simon #14 okay = false; break; } } else { break; } } if (okay) { position = i; } } } return position; } } }