How to play a spotify music stream - spotify

First of all, i am new to audio-programming, so bear with me.
I am trying to play spotify music with NAudio or BASS.Net or any other .net audio-library.
As far as i known, libspotify delivers music as raw PCM data. what is the sample rate of spotify stream (libspotify)?
From the spotify docs:
Samples are delivered as integers, see sp_audioformat. One frame consists of the same number of samples as there are channels. I.e. interleaving is on the sample level.
When i try to play a song, spotify makes a callback with a 8192 byte buffer
channels = 2
sample_rate = 44100
num_frames = 2048
I need a little help translating this information to NAudio terms.
I have also tried with a spotify to Bass.Net sample (BASSPlayer.cs). But i haven't heard a single note from my speakers yet.
I have tried to play an mp3-song with NAudio and Bass.NET and this works fine, so the speaker volume is ok.
https://github.com/Alxandr/SpotiFire/blob/master/SpotiFire.Server/BASSPlayer.cs

There is breakthrough with NAudio. This is what i came up with, by using the trial and error method. I'm not sure if this is the right way to calculate the parameters from sampleRate/channels...
But the song is playing :-)
IWavePlayer waveOutDevice = new WaveOut();
using (var pcmStream = new FileStream(PcmFile, FileMode.Open))
{
const int songDuration = 264000;
const int sampleRate = 44100;
const int channels = 2;
var waveFormat = WaveFormat.CreateCustomFormat(WaveFormatEncoding.Pcm, sampleRate * channels, 1, sampleRate * 2 * channels, channels, 16);
var waveStream = new RawSourceWaveStream(pcmStream, waveFormat);
waveOutDevice.Init(waveStream);
waveOutDevice.Play();
Thread.Sleep(songDuration);
waveOutDevice.Stop();
waveStream.Close();
waveOutDevice.Dispose();
}

Related

how to concatenate two wav audio files with 30 seconds of white sound using NAudio

I need to concatenate two wav audio files with 30 seconds of whute sound between them.
I want to use the NAudio library - or with any other way that work.
How to do it ?
( the different from any other question is that i need not only to make one audio file from two different audio files .. i also need to add silent between them )
Assuming your WAV files have the same sample rate and channel count, you can concatenate using FollowedBy and use SignalGenerator combined with Take to get the white noise.
var f1 = new AudioFileReader("ex1.wav");
var f2 = new SignalGenerator(f1.WaveFormat.SampleRate, f1.WaveFormat.Channels) { Type = SignalGeneratorType.White, Gain = 0.2f }.Take(TimeSpan.FromSeconds(5));
var f3 = new AudioFileReader("ex3.wav");
using (var wo = new WaveOutEvent())
{
wo.Init(f1.FollowedBy(f2).FollowedBy(f3));
wo.Play();
while (wo.PlaybackState == PlaybackState.Playing) Thread.Sleep(500);
}

Is there any way to sample audio using OpenSL on android with different sampling rates and buffer sizes?

I have downloaded the audio-echo app from the android NDK portal for opensl. Due to the lack of documentation I'm not able to identify how to change the sampling rate and buffer size of the audio in and out.
If anybody has any idea on how to:
Change the buffer size and sampling rate on OpenSL
Read the buffers to be fed to a C code to be processed
Fed to the output module of OpenSL to be fed to the speakers
Another alternative I feel is read it at the preferred sampling rate and buffer size but downsample and upsample in the code itself and use a circular buffer to get desired data. But how are we reading and feeding the data in openSL?
In the OpenSL ES API, there are calls to create either a Player or a Recorder:
SLresult (*CreateAudioPlayer) (
SLEngineItf self,
SLObjectItf * pPlayer,
SLDataSource *pAudioSrc,
SLDataSink *pAudioSnk,
SLuint32 numInterfaces,
const SLInterfaceID * pInterfaceIds,
const SLboolean * pInterfaceRequired
);
SLresult (*CreateAudioRecorder) (
SLEngineItf self,
SLObjectItf * pRecorder,
SLDataSource *pAudioSrc,
SLDataSink *pAudioSnk,
SLuint32 numInterfaces,
const SLInterfaceID * pInterfaceIds,
const SLboolean * pInterfaceRequired
);
Note that both of these take a SLDataSource *pAudioSrc parameter.
To use a custom playback rate or recording rate, you have to set up this data source properly.
I use an 11Khz playback rate using this code:
// Configure data format.
SLDataFormat_PCM pcm;
pcm.formatType = SL_DATAFORMAT_PCM;
pcm.numChannels = 1;
pcm.samplesPerSec = SL_SAMPLINGRATE_11_025;
pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
pcm.containerSize = 16;
pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
// Configure Audio Source.
SLDataSource source;
source.pFormat = &pcm;
source.pLocator = &bufferQueue;
To feed data to the speakers, a buffer queue is used that is filled by a callback. To set this callback, use SLAndroidSimpleBufferQueueItf, documented in section 8.12 SLBufferQueueItf of the OpenGL ES specification.

Raw audio playback in Allegro 5

I'm writing a MOD player, trying to playback a sample using Allegro5 raw stream capabilities, I can't figure out the exact init parameters for the stream to play the loaded sample data from the mod file.
This is what I have:
xf::ModLoader ml;
ml.loadFromFile("C:\\Users\\bubu\\Downloads\\agress.mod");
// getSampleLength() returns # of data words
int sample_length = ml.getSampleLength(1) * 2;
const int8_t* sample_data = ml.getSampleData(1);
ALLEGRO_MIXER* mixer = al_get_default_mixer();
ALLEGRO_AUDIO_STREAM* stream = al_create_audio_stream(1, sample_length, 8363, ALLEGRO_AUDIO_DEPTH_INT8, ALLEGRO_CHANNEL_CONF_1);
al_attach_audio_stream_to_mixer(stream, mixer);
al_set_audio_stream_gain(stream, 0.7f);
al_set_audio_stream_playmode(stream, ALLEGRO_PLAYMODE_ONCE);
al_set_audio_stream_playing(stream, true);
al_set_audio_stream_fragment(stream, (void*)sample_data);
al_drain_audio_stream(stream);
First of all, freq param is hardcoded for the test (8363Hz), but, playing back at the specified frequency I don't get what I expect, and al_drain_audio_stream() gets stuck forever playing garbage in a loop...
Any help would be appreciated.
At the very least, you need to be calling al_get_audio_stream_fragment before you call al_set_audio_stream_fragment. Typically you'd feed these streams in a while loop, while responding to the ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event. See the ex_saw example in the Allegro's source for some sample code: https://github.com/liballeg/allegro5/blob/master/examples/ex_saw.c

VLC-QT get the framerate of current video file

I use the vlc-qt lib and try to access the frames per second information of an openend video file.
The player:
_instance = new VlcInstance(VlcCommon::args(), this);
_player = new VlcMediaPlayer(_instance);
_media = new VlcMedia(file, true, _instance);
_player->openOnly(_media);
the player has a public function playbackRate() but it gives only the current playback ration, so it is 1 if no slowmotion is applied.
float playbackRate = _player->playbackRate();
I also tried to get it over the codec, but the codec itself is not a class but only an enum with possible codecnames.
How can I access the fps, so get back something like 30 frames per second?
Using python vlc.py:
Where self.player is:
self.Instance = vlc.Instance()
self.player = self.Instance.media_player_new()
It has a function get_fps()
def mspf(self):# Milliseconds per frame.
return int(1000 // (self.player.get_fps() or 25))
EDIT:
Having dug deeper, there appears to be no reference to fps in the vlc-qt sources, except where it offers fps as an experimental input to the Media::duplicate and Media::record functions within VlcMedia.cpp although fps is available within vlc

Media Foundation : mpeg4 stream from camera gets distorted when GOV length is greater than 1

I am using Media Foundation on client side to display live mpeg4 stream from AXIS Camera through RTSP server.
Client side video works very fine if i set GOV # camera = 1, i.e. camera will only send I-Frames. But if GOV is increased and camera starts sending P-Frames also, my video suddenly gets distorted at regular intervals. I cannot set GOV = 1 for always because it consumes a lot of bandwidth.
Following is the code for RequestSample method where i supply Samples to Media Foundation :
RTPFrame frame = null;
byte[] frameBytes = null;
frame = _VideoJitter.GetNextFrame();
frameBytes = frame.GetFrameAsBytes();
frame.FrameType= RTPFrame.PredictFrameType(frameBytes);
_videoEncapsulatedSample.ReadSampleFrom(frameBytes);
videoSample = _videoEncapsulatedSample.MfSample;
long timestamp = nextSampleTimestamp ?? 0;
videoSample.SetSampleTime(timestamp);
duration_video = (long)GetPresentationTime(frame);
videoSample.SetSampleDuration(duration_video);
nextSampleTimestamp = timestamp + duration_video;
if (frame.FrameType == FrameType.IFrame)
{
videoSample.SetUINT32(MFAttributesClsid.MFSampleExtension_CleanPoint, 1);
}
return videoSample;
Do i need to set any attribute for processing P-Frames??
Any help would be highly appreciated....
Update (2012/02/22) :
I ran some statistics and found that some times I-frames never reach client, i.e. suppose GOV = 15, so every 15th frame should be an I-Frame, but sometimes (at irregular intervals) client receives an I-Frame after 28 or 30 or 59 P-frames.
Any pointers ??
Thanks,
Prateek

Resources