I had 4mb, around 4min long ogg file to play as background music.
When i launch it , the music stops at 20sec
I cut it down to 50 sec and it occasionally stops at 35-40 sec play time.
generic = MediaPlayer.create(this, R.raw.rep2);
generic.setLooping(true);
generic.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
generic.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
As a solution i may consider cutting 4min track into several 50 sec tracks and play them sequentially.
What is the maximum track length, or music file size standard media player can play in android without stops?
Related
I am using grpc bidirectional streaming connection to upload images on remote server. I am splitting the given image into smaller chunks of 1MB and then perform upload operation. The uploading is working fine for the images around 4MB size but if size is > 10MB then the given deadline timer timeout and it fails always. Currently I have tested only for < 4MB and > 10MB size images.
Here is my upload function
bool FileUploadClient::upload_file(const std::string& upload_file_name)
{
bool upload_result = false;
if(m_grpc_fileupload_stub)
{
ClientContext m_context;
// set deadline timer
std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + std::chrono::seconds(10);
m_context.set_deadline(deadline);
FileUploadGrpc::FileUploadResponse file_upload_res;
std::vector<FileUploadGrpc::FileUploadRequest> upload_request_vect;
// split file contents into chunks as file is big in size
read_file_into_chunks(upload_file_name, upload_request_vect);
std::unique_ptr<::grpc::ClientWriter<::FileUploadGrpc::FileUploadRequest>> writer(
m_grpc_fileupload_stub->UploadFileToServer(&m_context, &file_upload_res));
// Send file contents chunk by chunk to grpc end
for(const auto& upload_req_msg : upload_request_vect)
{
if(!writer->Write(upload_req_msg))
{
break; // if write fails then break
}
else
{
// I want to reset deadline timer
}
}
writer->WritesDone();
Status status = writer->Finish();
upload_result = (status.ok() && (file_upload_res.status_code() == FileUploadGrpc::FileUploadStatusCode::OK));
if(!upload_result)
{
LOG_ERROR(log_prefix << ", grpc file upload failed for: " << upload_file_name);
}
}
return upload_result;
}
As I understood that in the above give deadline timer the RPC call to upload images < 4MB completes successfully but for 10MB size I have to increase the deadline timer suitable for 10MB and that is not good idea.
So regardless of image size how can I set/reset the deadline timer after every successful write operation. Or is there any better way to do that?
TL/DR: A simple echo program that records and plays back audio immediately is showing higher than expected latency.
I am working on a real-time audio broadcasting application. I have decided to use OpenAL to both capture and playback audio samples. I am planning on sending UDP packets with raw PCM data across a LAN network. My ideal latency between recording on one machine and playing back on another machine is 30ms. (A lofty goal).
As a test, I made a small program that records samples from a microphone and immediately plays them back to the host speakers. I did this to test the baseline latency.
However, I'm seeing an inherent latency of about 65 - 70 ms from simply recording the audio and playing it back.
I have reduced the buffer size that openAL uses to 100 samples at 44100 samples per second. Ideally, this would yield a latency of 2 - 3 ms.
I have yet to try this on another platform (MacOS / Linux) to determine if this is an OpenAL issue or a Windows issue.
Here's the code:
using std::list;
#define FREQ 44100 // Sample rate
#define CAP_SIZE 100 // How much to capture at a time (affects latency)
#define NUM_BUFFERS 10
int main(int argC, char* argV[])
{
list<ALuint> bufferQueue; // A quick and dirty queue of buffer objects
ALuint helloBuffer[NUM_BUFFERS], helloSource;
ALCdevice* audioDevice = alcOpenDevice(NULL); // Request default audio device
ALCcontext* audioContext = alcCreateContext(audioDevice, NULL); // Create the audio context
alcMakeContextCurrent(audioContext);
// Request the default capture device with a ~2ms buffer
ALCdevice* inputDevice = alcCaptureOpenDevice(NULL, FREQ, AL_FORMAT_MONO16, CAP_SIZE);
alGenBuffers(NUM_BUFFERS, &helloBuffer[0]); // Create some buffer-objects
// Queue our buffers onto an STL list
for (int ii = 0; ii < NUM_BUFFERS; ++ii) {
bufferQueue.push_back(helloBuffer[ii]);
}
alGenSources(1, &helloSource); // Create a sound source
short* buffer = new short[CAP_SIZE]; // A buffer to hold captured audio
ALCint samplesIn = 0; // How many samples are captured
ALint availBuffers = 0; // Buffers to be recovered
ALuint myBuff; // The buffer we're using
ALuint buffHolder[NUM_BUFFERS]; // An array to hold catch the unqueued buffers
alcCaptureStart(inputDevice); // Begin capturing
bool done = false;
while (!done) { // Main loop
// Poll for recoverable buffers
alGetSourcei(helloSource, AL_BUFFERS_PROCESSED, &availBuffers);
if (availBuffers > 0) {
alSourceUnqueueBuffers(helloSource, availBuffers, buffHolder);
for (int ii = 0; ii < availBuffers; ++ii) {
// Push the recovered buffers back on the queue
bufferQueue.push_back(buffHolder[ii]);
}
}
// Poll for captured audio
alcGetIntegerv(inputDevice, ALC_CAPTURE_SAMPLES, 1, &samplesIn);
if (samplesIn > CAP_SIZE) {
// Grab the sound
alcCaptureSamples(inputDevice, buffer, samplesIn);
// Stuff the captured data in a buffer-object
if (!bufferQueue.empty()) { // We just drop the data if no buffers are available
myBuff = bufferQueue.front(); bufferQueue.pop_front();
alBufferData(myBuff, AL_FORMAT_MONO16, buffer, samplesIn * sizeof(short), FREQ);
// Queue the buffer
alSourceQueueBuffers(helloSource, 1, &myBuff);
// Restart the source if needed
// (if we take too long and the queue dries up,
// the source stops playing).
ALint sState = 0;
alGetSourcei(helloSource, AL_SOURCE_STATE, &sState);
if (sState != AL_PLAYING) {
alSourcePlay(helloSource);
}
}
}
}
// Stop capture
alcCaptureStop(inputDevice);
alcCaptureCloseDevice(inputDevice);
// Stop the sources
alSourceStopv(1, &helloSource);
alSourcei(helloSource, AL_BUFFER, 0);
// Clean-up
alDeleteSources(1, &helloSource);
alDeleteBuffers(NUM_BUFFERS, &helloBuffer[0]);
alcMakeContextCurrent(NULL);
alcDestroyContext(audioContext);
alcCloseDevice(audioDevice);
return 0;
}
Here is an image of the waveform showing the delay in input sound and the resulting echo. This example is shows a latency of about 70ms.
Waveform with 70ms echo delay
System specs:
Intel Core i7-9750H
24 GB Ram
Windows 10 Home: V 2004 - Build 19041.508
Sound driver: Realtek Audio (Driver version 10.0.19041.1)
Input device: Logitech G330 Headset
Issue is reproducible on other Windows Systems.
EDIT:
I tried to use PortAudio to do a similar thing and achieved a similar result. I've determined that this is due to Windows audio drivers.
I rebuilt PortAudio with ASIO audio only and installed ASIO4ALL audio driver. This has achieved an acceptable latency of <10ms.
I ultimately resolved this issue by ditching OpenAL in favor of PortAudio and Steinberg ASIO. I installed ASIO4ALL and rebuilt PortAudio to accept only ASIO device drivers. I needed to use the ASIO SDK from Steinberg to do this. (Followed guide here). This has allowed me to achieve a latency of between 5 and 10 ms.
This post helped a lot: input delay with PortAudio callback and ASIO sdk
I get an average frame rate from the EVR renderer using the IQualProp::get_AvgFrameRate method. It worked well but after call of Pause/Run in the DirectShow graph I got wrong values of frame rate. Here some my solutions:
Standard solution:
bool Pause()
{
IMediaControl* pMediaControl;
pMediaControl->Pause();
}
bool Run()
{
IMediaControl* pMediaControl;
pMediaControl->Run();
}
After pMediaControl->Run() the renderer shows me the frame rate values in two times less than it is necessary. But during 10-15 sec those values are restored.
Via Stop() method:
bool Pause()
{
IMediaControl* pMediaControl;
pMediaControl->Stop();
pMediaControl->Pause();
}
bool Run()
{
IMediaControl* pMediaControl;
pMediaControl->Run();
}
Into the Pause() I add pMediaControl->Stop(). After Run() I get the right frame rate but the renderer freezes for 10-15 sec.
Using IMediaFilter::Run()
bool Pause()
{
IMediaControl* pMediaControl;
pMediaControl->Stop();
pMediaControl->Pause();
}
bool Run()
{
IMediaFilter* pMediaFilter;
pMediaFilter->Run(1000000); //delay 10ms
}
Here I got the nice result without freezing and wrong values. But CPU utilization is more in two times than before Pause().
Ideas?
I can return to my old schema, when I got an average frame rate by calculation of frames, but I would like to use the IQualProp::get_AvgFrameRate method.
I returned to the old schema. Rewrite the code of getting average FPS is better than the rework of three source filters
As part of a music player I am developing with C++/Qt, I am scanning all audio files with taglib to get the metadata for the database.
I noticed something interesting.
The first time after a restart, it takes about 100ms and 500ms on my system to create a TagLib::FileRef object. When I use the same file again to create a TagLib::FileRef it takes 0ms, even after I restart the musicplayer.
Here is the function I am using to test that:
bool suffixCheck(const QString &val)
{
if (val.endsWith(".mp3")) {
return true;
}
if (val.endsWith(".m4a")) {
return true;
}
if (val.endsWith(".ogg")) {
return true;
}
return false;
}
void doTaglibThing(const QString &path)
{
if (suffixCheck(path)) {
QElapsedTimer timer;
timer.start();
TagLib::FileRef f(path.toUtf8().data(),
true,
TagLib::AudioProperties::Accurate);
Q_UNUSED(f);
qDebug() << "End taglibThing" << timer.elapsed();
}
}
Why is this? I assume that taglib somehow "remembers" the objects. How can I make it so that taglib doesn't remember and always actually has to read the file.
I want to optimize the library scanning function and I don't always want to restart the whole system to check how changes to the code impact the first-run scan.
As suggested by Frank Osterfeld, the file data was still in disk cache.
Clearing the disk cache with
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
makes taglib re-read the file from the disk again.
A song is set as static in Phonon audio player. The loop works using aboutToFinish(). The problem is that there is a 1 sec delay at the end of the song, then the song repeats.
How can we avoid the delay? I have also stored in a temporary buffer (using QBuffer), for playing it. But it is not giving solution for looping issue.
musicpath="sound/sample.mp3";
Phonon::AudioOutput *audioOutput;
Phonon::VolumeSlider *volumeSlider;
Phonon::MediaObject *mediaObject;
mediaObject = new Phonon::MediaObject(this);
mediaObject->setCurrentSource(Phonon::MediaSource( musicpath));
connect(mediaObject, SIGNAL(aboutToFinish()),mediaObject,SLOT(stop()));
connect(mediaObject, SIGNAL(aboutToFinish()),mediaObject,SLOT(play()));
Phonon::createPath(mediaObject, audioOutput);
volumeSlider->setAudioOutput(audioOutput);
mediaObject->play();
I think best choice is checking for state of video is by using timer with 1 ms and play it if end
timer = new QTimer;
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timer_overflow()));
timer->start(1);
void MainWindow::timer_overflow()
{
if(ui->videoPlayer->isPaused())
{
video=Phonon::createPlayer(Phonon::VideoCategory,Phonon::MediaSource("video/back);
ui->videoPlayer->load(Phonon::MediaSource("video/background_video.wmv"));
ui->videoPlayer->play();
}
}