Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C++] substr

    Salve,

    volevo sapere se in C++ esistesse una specie di funzione per spezzettare una sequenza di bytes, mi spiego meglio. Sto studiando l'encoder LAME ed ho scoperto che per ragioni intenre accetta solo 2304 Samples (Stereo: 2x1152).

    Infatti la funzione:

    beInitStream(&beConfig, &dwSamples, &dwMP3Buffer, &hbeStream);
    mi ritorna sempre:

    dwSamples = 2304;

    Ora, ho settato la waveform API per accturare 5880 Bytes in 30 buffers (176400 bytes, ovvero 1 secondo di audio PCM, 441Khz, 16bit, stereo) ... (44100 *2 *2)

    Per motivi che non vi sto ora a spiegare non posso settare il buffer per catturare 2304 Bytes o multipli...mi verrebbe un'audio pieno di schioppi e rumore.

    Arriviamo alla CALLBACK_EVENT dove il sistema mi notifica che il buffer di 5880 bytes è "filled" quindi posso usarlo per convertirlo in MP3 tramite la beEncodeChuck() della DLL di Lame-enc.

    codice:
    while(1)
    {
    	// CALLBACK EVENT
    	WaitForSingleObject(hevent, INFINITE);
    
    	if(buff[k].dwFlags & WHDR_DONE)
    	{
    		//buff[k].lpData is 5880 Bytes long...
    
    		while(...)
    		{
    			//encode();
    		}
    		waveInAddBuffer(hwi, &buff[k], sizeof(WAVEHDR));
    	}
    
    	if(k == num_buffers -1)
    		k=0;
    	else
    		k++;
    }
    Tuttavia la beEncodeChuck() si aspetta che le passi 2304 Samples al massimo...ne consegue che la potrò chiamare 3 volte con questi valori:

    2304 bytes, 2304 bytes e 1272 bytes = 5880 bytes!
    La mia domanda è: se ho un buffer con size 5880 bytes, come faccio a leggerlo a pezzi?

    grazie
    Alla batteria dai retta ballA

  2. #2
    in poche parole mi piacerebbe trasformare questo blocco che legge da file. (io invece dovrei leggere da buffer LPSTR:

    codice:
    // Init the MP3 Stream
    beInitStream(&bec, &dwSamples, &dwMP3Buffer, &hbeStream);
    
    // Allocate MP3 buffer
    PBYTE pMP3Buffer = new BYTE[dwMP3Buffer];
    
    // Allocate WAV buffer
    PSHORT pWAVBuffer = new SHORT[dwSamples];
    
    // Convert All PCM samples
    while ( ( dwRead = fread(pWAVBuffer, sizeof(SHORT), dwSamples, pFileIn)) > 0 )
    {
    	// Encode samples
    	beEncodeChunk(hbeStream, dwRead, pWAVBuffer, pMP3Buffer, &dwWrite);
    
    	// write dwWrite bytes that are returned in tehe pMP3Buffer to disk
    	fwrite(pMP3Buffer,1,dwWrite,pFileOut) != dwWrite)
    }
    Alla batteria dai retta ballA

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Per questo lavoro il C/C++ mette a disposizione i

    puntatori

    Utilizzane uno spostandolo dove ti serve prima di passare alla funzione di encoding.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  4. #4
    per adesso ho provato una cosa del genere, pensi sia l'approccio giusto?

    codice:
    int main()
    {
    	const char* buffer = "01234567890HELLOWORLDHOWAREYOU??";
    	char* chunk        = new char[10];
    
    	int dwChunkLen     = 10;
    	int dwChunkSeek    = 0;
    	int dwLoop         = 0;
    
    	while(dwLoop < 4)
    	{
    		memcpy(chunk, buffer+dwChunkSeek, dwChunkLen);
    		printf("%s\n", chunk);
    		++dwLoop;
    		dwChunkSeek += dwChunkLen;
    	}
    
    	delete[] chunk;
    
    	system("pause");
    	return 0;
    }
    Alla batteria dai retta ballA

  5. #5
    diciamo così:

    codice:
    int main()
    {
    	DWORD dwBuffer     = 32;
    	DWORD dwChunk      = 10;
    	LPSTR sBuffer      = new char[dwBuffer];
    	LPSTR sChunk       = new char[dwChunk];
    
    	sBuffer = "01234567890HELLOWORLDHOWAREYOU??";
    
    	DWORD dwChunkLen   = dwChunk;
    	DWORD dwChunkSeek  = 0;
    	DWORD dwLoop       = 0;
    
    	while(dwLoop < 4)
    	{
    		memcpy(sChunk, sBuffer+dwChunkSeek, dwChunkLen);
    		printf("%s\n", sChunk);
    		++dwLoop;
    		dwChunkSeek += dwChunkLen;
    	}
    
    	system("pause");
    	return 0;
    }
    ora però il valore della condizione d'uscita dalla while lo scritta io, si può fare in automatico, ad esempio: DWORD dwExit = ceil(32/10) ?? e devo fare il cast di ceil?

    Inoltre se volessi leggere il contenuto di un LPSTR in un SHORT dovrei fare cosi?

    codice:
    memcpy(pWAVChunk, sBuffer+dwChunkSeek*sizeof(SHORT), dwChunkLen);
    // dove: PSHORT pWAVBuffer = new SHORT[n]
    grazie
    Alla batteria dai retta ballA

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Non ho letto tutto (anche perchè tu proponi sempre n risposte ed m domande ...) ma penso possa essere l'approccio giusto, a meno di errori "tecnici" ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    allora con questo codice credo di rendere bene l'idea su quello che voglio fare.

    codice:
    #define WIN32_LEAN_AND_MEAN
    #define _CRT_SECURE_NO_WARNINGS
    
    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    
    const LPSTR strFileIn = TEXT("C:\\Users\\giangaetano\\Desktop\\testcase.wav");
    const LPSTR strFileOut = TEXT("C:\\Users\\giangaetano\\Desktop\\marameo.wav");
    
    int main()
    {
    	DWORD dwBuffer    = 100000;
    	DWORD dwChunk     = 2304;
    	LPSTR header      = new char[44];
    	PBYTE pWAVBuffer  = new BYTE[dwBuffer];
    	PBYTE pWAVChunk   = new BYTE[dwChunk];
    	FILE* pFileIn     = NULL;
    	DWORD dwRead      = 0;
    
    	// Slurp file: pWAVBuffer contains all the data
    	pFileIn = fopen( strFileIn, "rb" );
    	if (pFileIn == NULL)
    	{
    		printf("cannot open file!\n");
    		return -1;
    	}
    	dwRead = fread(header, 1, 44, pFileIn);
    	dwRead = fread(pWAVBuffer, sizeof(BYTE), dwBuffer, pFileIn);
    	fclose(pFileIn);
    	printf("%d\n", dwRead);
    
    	// Loop thru data:
    	DWORD dwLoopExit  = (DWORD)ceil((double)dwBuffer/dwChunk);
    	DWORD dwChunkSeek = 0;
    	DWORD dwLoop      = 0;
    
    	FILE* pFileOut;
    	pFileOut = fopen( strFileOut, "wb" );
    	fwrite(header, 1, 44, pFileOut);
    
    	while (dwLoop < dwLoopExit)
    	{
    		memcpy(pWAVChunk, pWAVBuffer + dwChunkSeek, dwChunk);
    		dwChunkSeek += dwChunk;
    		++dwLoop;
    		fwrite(pWAVChunk, sizeof(BYTE), dwChunk, pFileOut);
    		printf("%d\n", dwChunkSeek);
    	}
    	fclose(pFileOut);
    
    	delete[] header;
    	delete[] pWAVBuffer;
    	delete[] pWAVChunk;
    
    	system("pause");
    	return 0;
    }
    Il codice serve solo a scopo didattico. Leggo in memoria l'intero contenuto di un file e lo riscrivo a chunks di 2304 bytes in un'altro file...il File di origine pesa 100040 Bytes (ma i primi 44 bytes sono di header, non mi servono)

    Calcolando che lo voglio salvare in un unico file man mano a pezzetti di 2304 bytes l'uno, dovrò fare ceil((double)100000/2304) = 44 cicli while, di qui 43 sono chunks pieni mentre l'ultimo e nullpadded in parte...come posso evitare il nulpadded e salvare solo i testanti 928 bytes??
    Alla batteria dai retta ballA

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Calcola la parte intera della divisione

    100000/2304

    ovvero

    43

    e poi il resto

    100000-(43*2304)

    ovvero

    928

    A questo punto fai il ciclo con la scrittura "piena" per 43 volte e dopo il ciclo fai una sola scrittura della parte restante, ovvero dei 928 byte
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  9. #9
    grazie, a questo punto mi conviene fare una cosa che può sembrare andare per le lunghe ma credo funzionerà:

    codice:
    #include <stdlib.h>
    #include <map>
    #include <math.h>
    
    int main()
    {
    	std::map<int, int> hashChunk;
    
    	int dwBuffer    = 100000;
    	int dwChunk     = 2304;
    	int dwNumChunks = (int)ceil((double)dwBuffer/dwChunk);
    	int dwLastChunk = dwChunk-((dwChunk*dwNumChunks)-dwBuffer);
    
    	int k = 0;
    	while (k < dwNumChunks - 1)
    	{
    		hashChunk.insert(std::make_pair(k, dwChunk));
    		++k;
    	}
    	hashChunk.insert(std::make_pair(k, dwLastChunk));
    
    	int g = 0;
    	while (g < dwNumChunks)
    	{
    		printf("%d -> %d\n", g, hashChunk[g]);
    		++g;
    	}
    
    	system("pause");
    	return 0;
    }
    obbero un hash che contiene in key il numero del "ciclo" ed in value il relativo "buffer len" da usare...modificando ad esempio il codice precedente così:

    codice:
    while(dwLoop < 4)
    {
    	memcpy(sChunk, sBuffer+dwChunkSeek, hashChunk[dwLoop]);
    	printf("%s\n", sChunk);
    	++dwLoop;
    	dwChunkSeek += dwChunkLen;
    }
    di più non so che fare...(se non dormire)
    Alla batteria dai retta ballA

  10. #10
    anche se hora però sono bloccato quì:

    codice:
    	while(1)
    	{
    		if(stop_thread_flag)
    			break;
    		// CALLBACK EVENT
    		WaitForSingleObject(hevent, INFINITE);
    
    		if(buff[k].dwFlags & WHDR_DONE)
    		{
    			// Encode chunk by chunk
    			while(dwLoop < dwNumChunks)
    			{
    				// copy part of the buffer
    				memcpy(
    pWAVChunk, buff[k].lpData + dwChunkSeek, hashChunk[dwLoop]);
    				// Encode samples
    				printf("encode\n");
    				result = beEncodeChunk(hbeStream, 
    hashChunk[dwLoop], pWAVChunk, pMP3Buffer, &dwWrite);
    				// Save
    				hFile.write((LPSTR)pMP3Buffer, dwWrite);
    				dwChunkSeek += hashChunk[dwLoop];
    				++dwLoop;
    			}
    			dwLoop      = 0;
    			dwChunkSeek = 0;
    			waveInAddBuffer(hwi, &buff[k], sizeof(WAVEHDR));
    		}
    mi va in errore: beEncodeChunk() ma sembra tutto giusto :-(
    Alla batteria dai retta ballA

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.