Извлечение необработанных аудиоданных из файлов WAV с использованием libsndfile в Stack Overflow

Я работаю над приложением, которое обеспечит аудиовход для какого-либо устройства. Устройство ожидает, что аудиовход будет предоставлен в виде потока необработанных аудиоданных (16 бит, 48 кГц). Итак, независимо от формата аудиоданных в волновом файле (8-битный, 16-битный, 24-битный, 32-битный и т. Д.), Я хочу извлечь необработанные аудиоданные из файла WAV. Я планировал использовать libsndFile библиотека для этого. Я изменил пример кода C ++ библиотеки libsndfile, как показано ниже:

#include "stdafx.h"#include <sndfile.hh>

static void create_file (const char * fname, int format, const short* buffer,const   unsigned int& len)
{
// file ;
int channels = 1 ;  //A Mono wave file.
int srate = 48000 ;

printf ("Creating file named '%s'\n", fname) ;

SndfileHandle file = SndfileHandle (fname, SFM_WRITE, format, channels, srate) ;

int x = file.write (buffer, len) ;
}

static void read_file (const char * fname)
{
SndfileHandle       file ;

file = SndfileHandle (fname) ;

const unsigned int uiBuffLen = file.channels() * file.frames();
short* data = new short [uiBuffLen] ;
memset(data,0x00,uiBuffLen);

int x = file.command(SFC_SET_SCALE_FLOAT_INT_READ, (void*)data, uiBuffLen);
file.read (data, uiBuffLen) ;   //Read the audio data in the form of 16 bit short integer

//Now create a new wave file with audio data in the form of 16 bit short integers
create_file ("ConvertedFile.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16,data, (const unsigned int&)uiBuffLen) ;

//Now fill a buffer containing audio data and dump it into a file so that the same can be fed to a device expecting the raw audio data

unsigned char* bytBuffer = new unsigned char[uiBuffLen*2];
memset(bytBuffer, 0x00, uiBuffLen*2);
file.readRaw(bytBuffer, uiBuffLen*2);

FILE * pFile;
pFile = fopen ("RawAudio.dat","w");
if (pFile!=NULL)
{
fwrite(bytBuffer, 1, uiBuffLen*2, pFile);
fclose (pFile);
}

delete [] data;
delete [] bytBuffer;
}

int _tmain(int argc, _TCHAR* argv[])
{
//The sample file is a Mono file containing audio data in float format.
const char * fname = "MonoWavFile.wav" ;

read_file (fname) ;

return 0;
}

Ну, приведенный выше код может выглядеть ужасно, но сейчас я просто ищу идею. Я использую файл «MonoWaveFile.wav», который является монофоническим файлом и содержит аудиоданные в виде 32-битных значений с плавающей запятой.
Я создаю новый файл «ConvertedFile.wav», используя библиотеку libsndfile. Этот файл содержит аудиоданные в 16-битном формате PCM. Я играю этот файл в медиаплеере и вижу, что преобразование выполнено правильно.

Затем я создаю другой файл «RawAudio.dat», чтобы сохранить только аудиоданные, которые я могу использовать для подачи аудиовхода на устройство. Файл создается, и когда я отправляю его на устройство, звук не работает вообще. Это указывает на то, что я делаю что-то ужасно неправильно. Кто-нибудь может дать мне знать, что я делаю неправильно? Я никогда раньше не работал над чем-либо подобным, поэтому буду признателен, если получу какую-либо помощь.

0

Решение

я использовал sf_open_virtual,
Я сделал еще один буфер, который я заполнил, используя sf_open_virtual, Затем я использовал этот «другой буфер» для подачи пакетов RTP.
Поэтому я думаю, это то, что вам нужно.

У меня есть проблемы, делающие это другие направления от пакета RTP до файла.

//============================================================================
// Name        : libsndfile_demo.cpp
// Author      :
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <string.h>
#include "sndfile.h"#include <assert.h>
#include <unistd.h>using namespace std;

typedef struct
{   sf_count_t offset, length ;
unsigned char data [160] ;
} VIO_DATA ;FILE *checker;
const void* old_ptr = NULL;

static sf_count_t vfget_filelen (void *user_data)
{
VIO_DATA *vf = (VIO_DATA *) user_data ;

return vf->length ;
} /* vfget_filelen */

static sf_count_t vfseek (sf_count_t offset, int whence, void *user_data)
{
VIO_DATA *vf = (VIO_DATA *) user_data ;

switch (whence)
{   case SEEK_SET :
vf->offset = offset ;
break ;

case SEEK_CUR :
vf->offset = vf->offset + offset ;
break ;

case SEEK_END :
vf->offset = vf->length + offset ;
break ;
default :
break ;
} ;

return vf->offset ;
} /* vfseek */

static sf_count_t vfread (void *ptr, sf_count_t count, void *user_data)
{
VIO_DATA *vf = (VIO_DATA *) user_data ;

/*
**  This will brack badly for files over 2Gig in length, but
**  is sufficient for testing.
*/
if (vf->offset + count > vf->length)
count = vf->length - vf->offset ;

memcpy (ptr, vf->data + vf->offset, count) ;
vf->offset += count ;

return count ;
} /* vfread */

static sf_count_t vfwrite (const void *ptr, sf_count_t count, void *user_data)
{
static int skip = 0;

//TODO: Why this is working ?!?!?!
if (skip < 1)
{
skip++;
return count;
}

//SendTo RTP packetizer instead of writing to file
fwrite(ptr, count, 1, checker);

return count ;
} /* vfwrite */

static sf_count_t vftell (void *user_data)
{
VIO_DATA *vf = (VIO_DATA *) user_data ;

return vf->offset ;
} /* vftell */int main()
{
SF_INFO writing_sfinfo;
writing_sfinfo.channels = 1;
writing_sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_GSM610;
writing_sfinfo.samplerate = 8000;
assert(true == sf_format_check(&writing_sfinfo));

SF_INFO reading_sfinfo;
memset(&reading_sfinfo, 0, sizeof(reading_sfinfo));

SNDFILE *input = sf_open("/home/georgi/Downloads/thank_you_60.PCMA", SFM_READ, &reading_sfinfo);
checker = fopen("/home/georgi/Downloads/checker.wav", "w+");

short file_data[reading_sfinfo.channels * 160];
int read_frames = 0;

SF_VIRTUAL_IO vio ;

// Set up pointers to the locally defined functions.
vio.get_filelen = vfget_filelen ;
vio.seek = vfseek ;
vio.read = vfread ;
vio.write = vfwrite ;
vio.tell = vftell ;

VIO_DATA vio_data ;
// Set virtual file offset and length to zero.
vio_data.offset = 0 ;
vio_data.length = 0 ;SNDFILE *virt_file = sf_open_virtual (&vio, SFM_WRITE, &writing_sfinfo, &vio_data);

int old_length = 0;
while ((read_frames = sf_readf_short(input, file_data, 160)))
{
sf_writef_short(virt_file, file_data, read_frames);
}

sf_close(virt_file);
sf_close(input);
fclose(checker);

return 0;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]