I've been trying to process speech on a stm32f407ve development board for some time now, which makes me wonder if the ADC is really set up to precisely sample the values. CMSIS FFT Functions. But when I try to couple it with the ADC in continuous conversion to sample a sine signal, it doesn't seem to sample well periodically. I put a sine signal into it from a frequency test of a 1khz sine wave from an internet video with a plug that I take out of some headphones, which by the way I already tested that it works correctly with an oscilloscope. So... this one from the development board is obviously not from a DSP but its ADC should work correctly for this type of application? Here is my code, obviously I made sure that the test was emitting voltage before the debug.
#include "main.h"
#include "arm_math.h"
#include "arm_const_structs.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define Fs 4096;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN PV */
#define SIGNAL_BUFFER_LENGTH 4096
float signalBuffer[2*SIGNAL_BUFFER_LENGTH];
float fftBuffer[2*SIGNAL_BUFFER_LENGTH];
float magnitudes[SIGNAL_BUFFER_LENGTH];
/* USER CODE END PV */
uint32_t k;
uint32_t cont1,cont2;
uint32_t start;
uint32_t stopi;
uint32_t delta;
float32_t maxValue; /* Max FFT value is stored here */
uint32_t maxIndex;
float frecuencia=10.0;
float32_t Ts;
float tiempo;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
#define ARM_CM_DEMCR (*(uint32_t*)0xE000EDFC)
#define ARM_CM_DWT_CTRL (*(uint32_t*)0xE0001000)
#define ARM_CM_DWT_CYCCNT (*(uint32_t*)0xE0001004)
if(ARM_CM_DWT_CTRL !=0){
ARM_CM_DEMCR |= 1<<24;
ARM_CM_DWT_CYCCNT =0;
ARM_CM_DWT_CTRL |= 1<<0;
}
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
Ts=1.0/(float)Fs;
HAL_ADC_Start(&hadc1);
for(k=0;k<2*SIGNAL_BUFFER_LENGTH;k+=2 )
{
signalBuffer[k]=HAL_ADC_GetValue(&hadc1);
}
k++;
//signalBuffer[0]=0;
//start= ARM_CM_DWT_CYCCNT;
arm_cfft_f32(&arm_cfft_sR_f32_len4096,signalBuffer,0,1);
signalBuffer[0]=0;
arm_cmplx_mag_f32(signalBuffer,magnitudes,4096);
arm_max_f32(magnitudes, 4096, &maxValue, &maxIndex);
//stopi = ARM_CM_DWT_CYCCNT;
//delta=stopi-start;
//tiempo=delta/8.0E07*1000.0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
You are just calling the function to take a single reading over and over in a loop. There is no reason to think that each pass through this loop will take the same amount of time. You need to set the ADC to be triggered from a timer in order to have some kind of reproducible sample rate.
In general the internal ADC is not of suitable quality for audio use. There is an external audio codec fitted to this board, look at the example projects in the Stm32CubeF4 package.
In Minix 3.1.2a I've a struct "struct proc" where the PCB of any process stored,
but I've a problem when adding new attribute "p_currenthash" in the code below to this struct. I can't change its value except using a constant defined by #define directive; otherwise, the system stops responding. For clarity here is the structure:
struct proc {
struct stackframe_s p_reg; /* process' registers saved in stack frame */
#if (CHIP == INTEL)
reg_t p_ldt_sel; /* selector in gdt with ldt base and limit */
struct segdesc_s p_ldt[2+NR_REMOTE_SEGS]; /* CS, DS and remote segments */
#endif
#if (CHIP == M68000)
/* M68000 specific registers and FPU details go here. */
#endif
proc_nr_t p_nr; /* number of this process (for fast access) */
struct priv *p_priv; /* system privileges structure */
short p_rts_flags; /* process is runnable only if zero */
short p_misc_flags; /* flags that do suspend the process */
char p_priority; /* current scheduling priority */
char p_max_priority; /* maximum scheduling priority */
char p_ticks_left; /* number of scheduling ticks left */
char p_quantum_size; /* quantum size in ticks */
struct mem_map p_memmap[NR_LOCAL_SEGS]; /* memory map (T, D, S) */
clock_t p_user_time; /* user time in ticks */
clock_t p_sys_time; /* sys time in ticks */
struct proc *p_nextready; /* pointer to next ready process */
struct proc *p_caller_q; /* head of list of procs wishing to send */
struct proc *p_q_link; /* link to next proc wishing to send */
message *p_messbuf; /* pointer to passed message buffer */
int p_getfrom_e; /* from whom does process want to receive? */
int p_sendto_e; /* to whom does process want to send? */
sigset_t p_pending; /* bit map for pending kernel signals */
char p_name[P_NAME_LEN]; /* name of the process, including \0 */
int p_endpoint; /* endpoint number, generation-aware */
#if DEBUG_SCHED_CHECK
int p_ready, p_found;
#endif
char p_currenthash; /* hash */
};
Now, suppose I want to set its value. Initially I use the constant defined below.
#define NONE -1
register struct proc *rp;
rp->p_currenthash=NONE;
That works fine, but this: rp->p_currenthash=0 ; will cause the program to stop responding.
Any suggestions will be appreciated
Here's the main initialization in main():
/* Start the ball rolling. */
struct boot_image *ip; /* boot image pointer */
register struct proc *rp; /* process pointer */
register struct priv *sp; /* privilege structure pointer */
register int i, s;
int hdrindex; /* index to array of a.out headers */
phys_clicks text_base;
vir_clicks text_clicks, data_clicks;
reg_t ktsb; /* kernel task stack base */
struct exec e_hdr; /* for a copy of an a.out header */
/* Initialize the interrupt controller. */
intr_init(1);
/* Clear the process table. Anounce each slot as empty and set up mappings
* for proc_addr() and proc_nr() macros. Do the same for the table with
* privilege structures for the system processes.
*/
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
rp->p_rts_flags = SLOT_FREE; /* initialize free slot */
rp->p_nr = i; /* proc number from ptr */
rp->p_currenthash=NONE;
rp->p_endpoint = _ENDPOINT(0, rp->p_nr); /* generation no. 0 */
(pproc_addr + NR_TASKS)[i] = rp; /* proc ptr from number */
}
for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
sp->s_proc_nr = NONE; /* initialize as free */
sp->s_id = i; /* priv structure index */
ppriv_addr[i] = sp; /* priv ptr from number */
}
/* Set up proc table entries for processes in boot image. The stacks of the
* kernel tasks are initialized to an array in data space. The stacks
* of the servers have been added to the data segment by the monitor, so
* the stack pointer is set to the end of the data segment. All the
* processes are in low memory on the 8086. On the 386 only the kernel
* is in low memory, the rest is loaded in extended memory.
*/
/* Task stacks. */
ktsb = (reg_t) t_stack;
for (i=0; i < NR_BOOT_PROCS; ++i) {
ip = &image[i]; /* process' attributes */
rp = proc_addr(ip->proc_nr); /* get process pointer */
ip->endpoint = rp->p_endpoint; /* ipc endpoint */
rp->p_max_priority = ip->priority; /* max scheduling priority */
rp->p_priority = ip->priority; /* current priority */
rp->p_quantum_size = ip->quantum; /* quantum size in ticks */
rp->p_ticks_left = ip->quantum; /* current credit */
strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
(void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
priv(rp)->s_flags = ip->flags; /* process flags */
priv(rp)->s_trap_mask = ip->trap_mask; /* allowed traps */
priv(rp)->s_call_mask = ip->call_mask; /* kernel call mask */
priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to; /* restrict targets */
if (iskerneln(proc_nr(rp))) { /* part of the kernel? */
if (ip->stksize > 0) { /* HARDWARE stack size is 0 */
rp->p_priv->s_stack_guard = (reg_t *) ktsb;
*rp->p_priv->s_stack_guard = STACK_GUARD;
}
ktsb += ip->stksize; /* point to high end of stack */
rp->p_reg.sp = ktsb; /* this task's initial stack ptr */
text_base = kinfo.code_base >> CLICK_SHIFT;
/* processes that are in the kernel */
hdrindex = 0; /* all use the first a.out header */
} else {
hdrindex = 1 + i-NR_TASKS; /* servers, drivers, INIT */
}
/* The bootstrap loader created an array of the a.out headers at
* absolute address 'aout'. Get one element to e_hdr.
*/
phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
(phys_bytes) A_MINHDR);
/* Convert addresses to clicks and build process memory map */
text_base = e_hdr.a_syms >> CLICK_SHIFT;
text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0; /* common I&D */
data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
rp->p_memmap[T].mem_phys = text_base;
rp->p_memmap[T].mem_len = text_clicks;
rp->p_memmap[D].mem_phys = text_base + text_clicks;
rp->p_memmap[D].mem_len = data_clicks;
rp->p_memmap[S].mem_phys = text_base + text_clicks + data_clicks;
rp->p_memmap[S].mem_vir = data_clicks; /* empty - stack is in data */
/* Set initial register values. The processor status word for tasks
* is different from that of other processes because tasks can
* access I/O; this is not allowed to less-privileged processes
*/
rp->p_reg.pc = (reg_t) ip->initial_pc;
rp->p_reg.psw = (iskernelp(rp)) ? INIT_TASK_PSW : INIT_PSW;
/* Initialize the server stack pointer. Take it down one word
* to give crtso.s something to use as "argc".
*/
if (isusern(proc_nr(rp))) { /* user-space process? */
rp->p_reg.sp = (rp->p_memmap[S].mem_vir +
rp->p_memmap[S].mem_len) << CLICK_SHIFT;
rp->p_reg.sp -= sizeof(reg_t);
}
/* Set ready. The HARDWARE task is never ready. */
if (rp->p_nr != HARDWARE) {
rp->p_rts_flags = 0; /* runnable if no flags */
lock_enqueue(rp); /* add to scheduling queues */
} else {
rp->p_rts_flags = NO_MAP; /* prevent from running */
}
/* Code and data segments must be allocated in protected mode. */
alloc_segments(rp);
}
register struct proc *rp;
rp->p_currenthash=NONE;
rp is an uninitialized pointer; it isn't pointing to a valid struct proc object, and so dereferencing it leads to undefined behavior. The fact that this didn't crash when assigning -1 was pure luck. (bad luck, because it misled you to believe you were doing something meaningful)
acutually the problem not solved ,first the "p_currenthash" initialized in the main as shown above ,later in a function called pic_proc ,i've this code :
register struct proc **xpp; /* iterate over queue */
register struct proc *rp; /* process to run */
int q;
for (q=0; q < NR_SCHED_QUEUES; q++)
{
if ( (rp = rdy_head[q]) != NIL_PROC)
{
for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready)
{
if ((*xpp)->p_currenthash==NONE)
{
pick_val++;
}
}
}
}
that code works fine ,no inside the if if i changed the attribute "p_currenthash" the problem ocuured as bellow:
register struct proc **xpp; /* iterate over queue */
register struct proc *rp; /* process to run */
int q;
for (q=0; q < NR_SCHED_QUEUES; q++)
{
if ( (rp = rdy_head[q]) != NIL_PROC)
{
for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready)
{
if ((*xpp)->p_currenthash==NONE)
{
pick_val++;
(*xpp)->p_currenthash=1;
}
}
}
}
i really can't realize the problem.
I am trying to get the address of a system call that generates a sigsys signal! But I am getting the following error from gcc :
gcc emulator.c -fms-extensions
error: ‘siginfo_t’ has no member named ‘si_call_addr’
the code I am using is :
static void emulator(int nr, siginfo_t *siginfo, void *void_context)
{
ucontext_t *ctx = (ucontext_t *)(void_context);
int syscall;
char *buf;
ssize_t bytes;
size_t len;
if (siginfo->si_code != SYS_SECCOMP)
return;
if (!ctx)
return;
syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
printf("System call %d ADDR %X\n", syscall, siginfo->si_call_addr);
setcontext(ctx);
return;
}
the si_call_addr is defined as an anonymous structure in siginfo_t.
There's no si_call_addr in siginfo_t. You might be looking for the si_addr member.
Here's the siginfo_t provided by linux:
siginfo_t {
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
int si_trapno; /* Trap number that caused
hardware-generated signal
(unused on most architectures) */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
int si_overrun; /* Timer overrun count; POSIX.1b timers */
int si_timerid; /* Timer ID; POSIX.1b timers */
void *si_addr; /* Memory location which caused fault */
long si_band; /* Band event (was int in
glibc 2.3.2 and earlier) */
int si_fd; /* File descriptor */
short si_addr_lsb; /* Least significant bit of address
(since kernel 2.6.32) */
}
My task is to record wave file, convert it to ogg and pack it to the riff container. First two parts were done, but I have problems with the third part. I've found a source code which can solve my problem, but it doesn't work correctly.
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <memory.h>
#include <stdlib.h>
#include <mmreg.h>
#include <msacm.h>
#include <assert.h>
#include <math.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#define INPUT "record.wav"
#define OUTPUT "output_ogg.wav"
/* The following taken from the vorbis.acm sources */
/* Defines modes for encoding. Set this in 'fmt ' */
#define WAVE_FORMAT_VORBIS1 ((WORD)'O'+((WORD)'g'<<8)) // 0x674f("Og") ... Original stream compatible
#define WAVE_FORMAT_VORBIS2 ((WORD)'P'+((WORD)'g'<<8)) // 0x6750("Pg") ... Have independent header
#define WAVE_FORMAT_VORBIS3 ((WORD)'Q'+((WORD)'g'<<8)) // 0x6751("Qg") ... Have no codebook header
#define WAVE_FORMAT_VORBIS1P ((WORD)'o'+((WORD)'g'<<8)) // 0x676f("og") ... Original stream compatible
#define WAVE_FORMAT_VORBIS2P ((WORD)'p'+((WORD)'g'<<8)) // 0x6770("pg") ... Have independent header
#define WAVE_FORMAT_VORBIS3P ((WORD)'q'+((WORD)'g'<<8)) // 0x6771("qg") ... Have no codebook header
/* The 'fact' chunk required for compressed WAV files */
struct FACT {
unsigned long dwID;
unsigned long dwSize;
unsigned long dwSamples;
};
int main()
{
/* Open source file */
HMMIO hSrcWaveFile=mmioOpen(INPUT,NULL,MMIO_READ);
assert(hSrcWaveFile);
MMCKINFO SrcWaveFile;
mmioDescend(hSrcWaveFile,&SrcWaveFile,NULL,0);
assert(SrcWaveFile.ckid==mmioStringToFOURCC("RIFF",MMIO_TOUPPER));
assert(SrcWaveFile.fccType==mmioStringToFOURCC("WAVE",MMIO_TOUPPER));
MMCKINFO SrcWaveFmt;
/* Go to RIFF-WAVE*/
mmioDescend(hSrcWaveFile,&SrcWaveFmt,&SrcWaveFile,0);
assert(SrcWaveFmt.ckid==mmioStringToFOURCC("fmt ",0));
int SrcHeaderSize=SrcWaveFmt.cksize;
if(SrcHeaderSize<sizeof(WAVEFORMATEX))
SrcHeaderSize=sizeof(WAVEFORMATEX);
WAVEFORMATEX *SrcHeader=(WAVEFORMATEX *)new char[SrcHeaderSize];
ZeroMemory(SrcHeader,SrcHeaderSize);
/* Read fmt */
mmioRead(hSrcWaveFile,(char*)SrcHeader,SrcWaveFmt.cksize);
/* Leave the chunk */
mmioAscend(hSrcWaveFile,&SrcWaveFmt,0);
MMCKINFO SrcWaveData;
while(1){
MMRESULT Result=mmioDescend(hSrcWaveFile,&SrcWaveData,&SrcWaveFile,0);
assert(Result==0);
if(SrcWaveData.ckid==mmioStringToFOURCC("data",0))
break;
Result=mmioAscend(hSrcWaveFile,&SrcWaveData, 0);
assert(Result==0);
}
/* Destination header */
WAVEFORMATEX *DstHeader=(WAVEFORMATEX *)malloc(1024);
ZeroMemory(DstHeader,1024);
printf ("Going ACM!\n");
/* Suggest a format for us */
/* Try to coose the nmber 3 mode (whatever that is) */
DstHeader->wFormatTag = WAVE_FORMAT_VORBIS3;
DstHeader->nChannels = 2;
DstHeader->wBitsPerSample = 16;
DstHeader->nSamplesPerSec = 44100;
printf ("->acmFormatSuggest()\n");
if (acmFormatSuggest(NULL,SrcHeader,DstHeader,1024,ACM_FORMATSUGGESTF_WFORMATTAG))
printf ("ERROR: acmFormatSuggest()\n");
/* We shoudl have the DstHeader filled with data byt the ACM now */
/* Open destination */
HMMIO hDstWaveFile;
/* open the destination file */
hDstWaveFile=mmioOpen(OUTPUT,NULL,MMIO_CREATE|MMIO_WRITE);
assert(hDstWaveFile);
printf ("->mmioOpen() output.wav\n");
/* Create chunks */
MMCKINFO DstWaveFile;
DstWaveFile.fccType=mmioStringToFOURCC("WAVE",MMIO_TOUPPER);
mmioCreateChunk(hDstWaveFile,&DstWaveFile,MMIO_CREATERIFF);
printf ("->mmioCreateChunk() WAVE\n");
/* Create format chunk */
MMCKINFO DstWaveFmt;
DstWaveFmt.ckid=mmioStringToFOURCC("fmt ",0);
/* Create chunk write data and Ascend out of it */
mmioCreateChunk(hDstWaveFile,&DstWaveFmt,0);
printf ("->mmioCreateChunk() fmt\n");
mmioWrite(hDstWaveFile,(char*)DstHeader,sizeof(WAVEFORMATEX)+DstHeader->cbSize);
printf ("->mmioWrite() fmt header\n");
mmioAscend(hDstWaveFile,&DstWaveFmt,0);
printf ("->mmioAscend()\n");
/* fact chunk */
/* this is only my idea of what it should look like */
/* i found that some WAV files had more data than i write */
/* but that seems enough for most of apps i tested */
FACT DstFactChunk;
MMCKINFO FactChunk;
DstFactChunk.dwID = mmioStringToFOURCC ("fact", 0);
DstFactChunk.dwSamples = SrcWaveData.cksize / 4;
DstFactChunk.dwSize = sizeof (DstFactChunk) - sizeof (DstFactChunk.dwID) - sizeof (DstFactChunk.dwSize);
FactChunk.ckid = mmioStringToFOURCC ("fact", 0);
FactChunk.cksize = DstFactChunk.dwSize;
/* Calculate the time */
float TIME;
if (SrcHeader->nSamplesPerSec == 44100)
TIME = DstFactChunk.dwSamples / 44100.f;
mmioWrite (hDstWaveFile, (char *)&DstFactChunk, sizeof (DstFactChunk));
/* This ascend produced an error when i added this whole code */
/* to my Dialog based MFC full feature super duper app */
/* Don't know why really but i think that Write already moves the pointer */
/* past the chun sok this is unnecessery */
/* mmioAscend (hDstWaveFile, &FactChunk, 0); */
/* Create Data chunk */
MMCKINFO DstWaveData;
DstWaveData.ckid=mmioStringToFOURCC("data",0);
mmioCreateChunk(hDstWaveFile,&DstWaveData,0);
mmioAscend (hDstWaveFile, &DstWaveData, 0);
printf ("->mmioCreateChunk() data\n");
/* Print the data we have gathered so far */
printf ("------------Source-----------\n");
printf ("Format: \t\t%X\n", SrcHeader->wFormatTag);
printf ("Channels: \t\t%d\n", SrcHeader->nChannels);
printf ("Samples/Sec: \t\t%d\n", SrcHeader->nSamplesPerSec);
printf ("AverageBytes/Sec: \t%d\n", SrcHeader->nAvgBytesPerSec);
printf ("Bits/Sample: \t\t%d\n", SrcHeader->wBitsPerSample);
printf ("BlockAlign: \t\t%d\n", SrcHeader->nBlockAlign);
printf ("DataSize: \t\t%d\n", SrcWaveData.cksize);
printf ("Time: \t\t\t%.3f\n", TIME);
printf ("Samples: \t\t%d\n", DstFactChunk.dwSamples);
printf ("Extra: \t\t\t%d\n", SrcHeader->cbSize);
printf ("------------------------------\n");
printf ("\n------------Destination------\n");
printf ("Format: \t\t%X\n", DstHeader->wFormatTag);
printf ("Channels: \t\t%d\n", DstHeader->nChannels);
printf ("Samples/Sec: \t\t%d\n", DstHeader->nSamplesPerSec);
printf ("AverageBytes/Sec: \t%d\n", DstHeader->nAvgBytesPerSec);
printf ("Bits/Sample: \t\t%d\n", DstHeader->wBitsPerSample);
printf ("BlockAlign: \t\t%d\n", DstHeader->nBlockAlign);
printf ("Extra: \t\t\t%d\n", DstHeader->cbSize);
printf ("------------------------------\n");
DWORD maxFormatSize = 0;
MMRESULT ACMres;
/* Get the max possbile size from the system this really no necessery */
/* but i was experimenting a bit and so I left it here */
ACMres = acmMetrics( NULL, ACM_METRIC_MAX_SIZE_FORMAT, &maxFormatSize );
if (ACMres != MMSYSERR_NOERROR){
printf ("ERROR: acmMetrics()\n");
}
/* Open ACM stream */
HACMSTREAM acm = NULL;
MMRESULT Result=acmStreamOpen(&acm,NULL,SrcHeader,DstHeader,NULL,0,0,0);
printf ("->acmStreamOpen()\n");
if (Result != MMSYSERR_NOERROR){
printf ("ERROR: acmStreamOpen()\n");
exit (-1);
}
/* This is where the problem's begin, first the buffers */
/* Size of the dest/src is based on the size of src/dest */
DWORD DefaultWriteSize;
DWORD DefaultReadSize = SrcHeader->nBlockAlign * 1024;
/* If we know the dest */
/* Result=acmStreamSize(acm, DefaultWriteSize, &DefaultReadSize, ACM_STREAMSIZEF_DESTINATION); */
printf ("->acmStreamSize()\n");
/* If we know the source, well stay with the source PCM is less problematic */
Result = acmStreamSize (acm, DefaultReadSize, &DefaultWriteSize, ACM_STREAMSIZEF_SOURCE);
printf ("->acmStreamSize() gave us buffer size [%d]\n", DefaultWriteSize);
if (Result != MMSYSERR_NOERROR){
printf ("ERROR: acmStreamSize()\n");
exit (-1);
}
/* Allocate memory */
ACMSTREAMHEADER stream;
ZeroMemory(&stream,sizeof(stream));
stream.cbStruct=sizeof(stream);
stream.pbSrc=(BYTE*)GlobalAlloc(GMEM_FIXED,DefaultReadSize);
stream.cbSrcLength=DefaultReadSize;
stream.pbDst=(BYTE*)GlobalAlloc(GMEM_FIXED,DefaultWriteSize);
stream.cbDstLength=DefaultWriteSize;
/* Prepare header */
printf ("->acmStreamPrepareHeader()\n");
Result=acmStreamPrepareHeader(acm, &stream,0);
if (Result != MMSYSERR_NOERROR){
printf ("ERROR: acmStreamPrepareHeader()\n");
exit (-1);
}
/* The main encoding loop */
/* I'm pretty sure that before the actual reading of samples from the source */
/* I should feed the ACM some junk so that it would write the necessery headers */
/* that Ogg Vorbis requires */
/* but i dont know how much of that 'junk' i would have to write there */
/* i don't know if it can be junk */
/* well i'm pretty clueless here */
for(int RemainSize=SrcWaveData.cksize;RemainSize>0;){
// ????
int ReadSize=DefaultReadSize;
if(ReadSize>RemainSize)
ReadSize=RemainSize;
RemainSize-=ReadSize;
ReadSize=mmioRead(hSrcWaveFile,(char*)stream.pbSrc,ReadSize);
if (ReadSize == -1){
printf ("Can't read\n");
break;
}
stream.cbSrcLength=ReadSize;
/* Convert */
Result=acmStreamConvert(acm,&stream,0);
if (Result)
printf ("ERROR: acmStreamConvert()\n");
int WriteSize=stream.cbDstLengthUsed;
/* Wrtie data */
Result=mmioWrite(hDstWaveFile,(char*)stream.pbDst,WriteSize);
if (Result == -1){
printf ("Can't Write");
break;
}
/* Uncomment this if you want to see the buffer sizes */
/* printf ("READ[%d] :: WRITE[%d]\n", stream.cbSrcLengthUsed, stream.cbDstLengthUsed); */
}
/* Cleaup on Isle 5 !!! */
GlobalFree(stream.pbSrc);
GlobalFree(stream.pbDst);
acmStreamUnprepareHeader(acm,&stream,0);
acmStreamClose(acm,0);
mmioAscend(hSrcWaveFile,&SrcWaveData,0);
mmioAscend(hSrcWaveFile,&SrcWaveFile,0);
mmioAscend(hDstWaveFile,&DstWaveData,0);
mmioAscend(hDstWaveFile,&DstWaveFile,0);
free(DstHeader);
mmioClose(hSrcWaveFile,0);
mmioClose(hDstWaveFile,0);
delete[] SrcHeader;
return 0;
}
When I'm trying to execute this program, it shows me that acmFormatSuggest() and acmStreamOpen() failes. Please, help me finding the error.
acmFormatSuggest (by the way, what is the error code?) would possibly succeed if there is an ACM audio codec installed, which supports this format. There is no one available by default, do you actually have one installed?
Is there a function that returns how much space is free on a drive partition given a directory path?
check man statvfs(2)
I believe you can calculate 'free space' as f_bsize * f_bfree.
NAME
statvfs, fstatvfs - get file system statistics
SYNOPSIS
#include <sys/statvfs.h>
int statvfs(const char *path, struct statvfs *buf);
int fstatvfs(int fd, struct statvfs *buf);
DESCRIPTION
The function statvfs() returns information about a mounted file system.
path is the pathname of any file within the mounted file system. buf
is a pointer to a statvfs structure defined approximately as follows:
struct statvfs {
unsigned long f_bsize; /* file system block size */
unsigned long f_frsize; /* fragment size */
fsblkcnt_t f_blocks; /* size of fs in f_frsize units */
fsblkcnt_t f_bfree; /* # free blocks */
fsblkcnt_t f_bavail; /* # free blocks for unprivileged users */
fsfilcnt_t f_files; /* # inodes */
fsfilcnt_t f_ffree; /* # free inodes */
fsfilcnt_t f_favail; /* # free inodes for unprivileged users */
unsigned long f_fsid; /* file system ID */
unsigned long f_flag; /* mount flags */
unsigned long f_namemax; /* maximum filename length */
};
You can use boost::filesystem:
struct space_info // returned by space function
{
uintmax_t capacity;
uintmax_t free;
uintmax_t available; // free space available to a non-privileged process
};
space_info space(const path& p);
space_info space(const path& p, system::error_code& ec);
Example:
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
space_info si = space(".");
cout << si.available << endl;
Returns: An object of type space_info. The value of the space_info object is determined as if by using POSIX statvfs() to obtain a POSIX struct statvfs, and then multiplying its f_blocks, f_bfree, and f_bavail members by its f_frsize member, and assigning the results to the capacity, free, and available members respectively. Any members for which the value cannot be determined shall be set to -1.
With C++17
You can use std::filesystem::space:
#include <iostream> // only needed for screen output
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
fs::space_info tmp = fs::space("/tmp");
std::cout << "Free space: " << tmp.free << '\n'
<< "Available space: " << tmp.available << '\n';
}
You can use Qt class QStorageInfo to acquire hardisk free space:
First,you should include the header:
#include <QStorageInfo>
#define GB (1024 * 1024 * 1024)
bool CheckHardiskFree(const QString &strDisk)
{
QStorageInfo storage(strDisk);
if(storage.isValid() && storage.isReady())
{
double useGb =(storage.bytesTotal()-storage.bytesAvailable()) * 1.0/ GB;
double freeGb =storage.bytesAvailable() * 1.0 / GB;
double allGb =storage.bytesTotal()* 1.0 / GB;
return true;
}
return false;
}
One can get the output of a command into a program by using a pipe like this:
char cmd[]="df -h /path/to/directory" ;
FILE* apipe = popen(cmd, "r");
// if the popen succeeds read the commands output into the program with
while ( fgets( line, 132 , apipe) )
{ // handle the readed lines
}
pclose(apipe);
// -----------------------------------