public async Task <ServerAudioInfo> GrabFrameInfoAsync(ShoutcastStreamProcessor processor, ServerAudioInfo serverSentInfo) { ServerAudioInfo audioInfo = new ServerAudioInfo(); audioInfo.AudioFormat = StreamAudioFormat.MP3; //load the first byte byte lastByte = await processor.ReadByteFromSocketAsync(); while (true) //wait for frame sync { var curByte = await processor.ReadByteFromSocketAsync(); if (MP3Parser.IsFrameSync(lastByte, curByte)) //check if we're at the frame sync. if we are, parse some of the audio data { byte[] header = new byte[MP3Parser.HeaderLength]; header[0] = lastByte; header[1] = curByte; Array.Copy(await processor.ReadBytesFromSocketAsync(2), 0, header, 2, 2); if (!MP3Parser.IsValidHeader(header)) { lastByte = header[3]; continue; } else { audioInfo.HeaderData = header; audioInfo.SampleRate = (uint)MP3Parser.GetSampleRate(header); audioInfo.ChannelCount = (uint)MP3Parser.GetChannelCount(header); audioInfo.BitRate = (uint)MP3Parser.GetBitRate(header); break; } } else { lastByte = curByte; } } if (audioInfo.BitRate == 4294967294) { //if this gets hit, abort mission immediately. throw new ArithmeticException(); } return(audioInfo); }
private async Task <AudioEncodingProperties> ParseEncodingFromMediaAsync() { //grab the first frame and strip it for information AudioEncodingProperties obtainedProperties = null; IBuffer buffer = null; switch (AudioInfo.AudioFormat) { case StreamAudioFormat.MP3: { //load the first byte await socketReader.LoadAsync(1); byte lastByte = socketReader.ReadByte(); byteOffset += 1; metadataPos += 1; while (true) //wait for frame sync { await socketReader.LoadAsync(1); var curByte = socketReader.ReadByte(); if (MP3Parser.IsFrameSync(lastByte, curByte)) //check if we're at the frame sync. if we are, parse some of the audio data { byteOffset += 1; metadataPos += 1; byte[] header = new byte[MP3Parser.HeaderLength]; header[0] = lastByte; header[1] = curByte; await socketReader.LoadAsync(2); header[2] = socketReader.ReadByte(); header[3] = socketReader.ReadByte(); byteOffset += 2; metadataPos += 2; AudioInfo.SampleRate = (uint)MP3Parser.GetSampleRate(header); AudioInfo.ChannelCount = (uint)MP3Parser.GetChannelCount(header); AudioInfo.BitRate = (uint)MP3Parser.GetBitRate(header); if (AudioInfo.BitRate == 0) { throw new Exception("Unknown bitrate."); } break; } else { byteOffset += 1; metadataPos += 1; lastByte = curByte; } } //skip the entire first frame/sample to get back on track await socketReader.LoadAsync(mp3_sampleSize - MP3Parser.HeaderLength); buffer = socketReader.ReadBuffer(mp3_sampleSize - MP3Parser.HeaderLength); byteOffset += mp3_sampleSize - MP3Parser.HeaderLength; obtainedProperties = AudioEncodingProperties.CreateMp3((uint)AudioInfo.SampleRate, (uint)AudioInfo.ChannelCount, AudioInfo.BitRate); break; } case StreamAudioFormat.AAC: { //obtainedProperties = AudioEncodingProperties.CreateAac(0, 2, 0); throw new Exception("Not supported."); } case StreamAudioFormat.AAC_ADTS: { //load the first byte await socketReader.LoadAsync(1); byte lastByte = socketReader.ReadByte(); byteOffset += 1; metadataPos += 1; while (true) //wait for frame sync { await socketReader.LoadAsync(1); var curByte = socketReader.ReadByte(); if (AAC_ADTSParser.IsFrameSync(lastByte, curByte)) //check if we're at the frame sync. if we are, parse some of the audio data { byteOffset += 1; metadataPos += 1; byte[] header = new byte[AAC_ADTSParser.HeaderLength]; header[0] = lastByte; header[1] = curByte; await socketReader.LoadAsync(5); header[2] = socketReader.ReadByte(); header[3] = socketReader.ReadByte(); header[4] = socketReader.ReadByte(); header[5] = socketReader.ReadByte(); header[6] = socketReader.ReadByte(); byteOffset += 5; metadataPos += 5; //todo deal with CRC AudioInfo.SampleRate = (uint)AAC_ADTSParser.GetSampleRate(header); AudioInfo.ChannelCount = (uint)AAC_ADTSParser.GetChannelCount(header); //bitrate gets sent by the server. //bitRate = (uint)AAC_ADTSParser.GetBitRate(header); if (AudioInfo.BitRate == 0) { throw new Exception("Unknown bitrate."); } //skip the entire first frame/sample to get back on track await socketReader.LoadAsync(aac_adts_sampleSize - AAC_ADTSParser.HeaderLength); buffer = socketReader.ReadBuffer(aac_adts_sampleSize - AAC_ADTSParser.HeaderLength); byteOffset += aac_adts_sampleSize - AAC_ADTSParser.HeaderLength; obtainedProperties = AudioEncodingProperties.CreateAacAdts((uint)AudioInfo.SampleRate, (uint)AudioInfo.ChannelCount, AudioInfo.BitRate); break; } else { byteOffset += 1; metadataPos += 1; lastByte = curByte; } } } break; default: break; } metadataPos += buffer.Length; //very important or it will throw everything off! return(obtainedProperties); }