Exemplo n.º 1
0
//The recording stuff runs in its own thread
//this prevents dropouts in the recording, in case the
//bandwidth is smaller than the selected streaming bitrate
void* snd_rec_thread(void *data)
{
    int rb_read_bytes;
    int ogg_header_written;
    int enc_bytes_read;
    char *enc_buf = (char*)malloc(rec_rb.size * sizeof(char)*10);
    char *audio_buf = (char*)malloc(rec_rb.size * sizeof(short));

    ogg_header_written = 0;

    while(record)
    {
        pthread_cond_wait(&rec_cond, &rec_mut);

		rb_read_bytes = rb_read(&rec_rb, audio_buf);
		if(rb_read_bytes == 0)
			continue;

#if HAVE_LIBLAME
        if(!strcmp(cfg.rec.codec, "mp3"))
        {

            enc_bytes_read = lame_enc_encode(&lame_rec, (short int*)audio_buf, enc_buf,
                                rb_read_bytes/(2*cfg.rec.channel), rec_rb.size*10);
            bytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd);
        }
#endif
#if HAVE_LIBVORBIS
        if (!strcmp(cfg.rec.codec, "ogg"))
        {
            if(!ogg_header_written)
            {
                vorbis_enc_write_header(&vorbis_rec);
                ogg_header_written = 1;
            }

            enc_bytes_read = vorbis_enc_encode(&vorbis_rec, (short int*)audio_buf, 
                    enc_buf, rb_read_bytes/(2*cfg.rec.channel));
            bytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd);
        }
#endif
        if (!strcmp(cfg.rec.codec, "wav"))
        {
            //this permanently updates the filesize value in the WAV header
            //so we still have a valid WAV file in case of a crash
            wav_write_header(cfg.rec.fd, cfg.audio.channel,
                    cfg.audio.samplerate, /*bps*/ 16);
            
            bytes_written += fwrite(audio_buf, sizeof(char), rb_read_bytes, cfg.rec.fd); 
        }
    }

    fclose(cfg.rec.fd);
    free(enc_buf);
    free(audio_buf);
    return NULL;
}
Exemplo n.º 2
0
int wav_mix(char *in1, char *in2, char *out, int samplerate, int swap, int stereo) {
	FILE *f_in1 = NULL;
	FILE *f_in2 = NULL;
	FILE *f_out = NULL;

	char *bitstream_buf1 = NULL;
	char *bitstream_buf2 = NULL;
	char *p1;
	char *f1;
	char *p2;
	char *f2;
	short int zero = 0;
	long file_size1;
	long file_size2 = 0;

	/* combine two wavs */
	f_in1 = fopen(in1, "r");
	if(!f_in1) {
		syslog(LOG_ERR,"File [%s] cannot be opened for read.\n", in1);
		return 1;
	}
	if(in2 != NULL) {
		f_in2 = fopen(in2, "r");
		if(!f_in2) {
			fclose(f_in1);
			syslog(LOG_ERR,"File [%s] cannot be opened for read.\n", in2);
			return 1;
		}
	}
	for(int passOpen = 0; passOpen < 2; passOpen++) {
		if(passOpen == 1) {
			char *pointToLastDirSeparator = strrchr(out, '/');
			if(pointToLastDirSeparator) {
				*pointToLastDirSeparator = 0;
				mkdir_r(out, 0777);
				*pointToLastDirSeparator = '/';
			} else {
				break;
			}
		}
		f_out = fopen(out, "w");
		if(f_out) {
			break;
		}
	}
	if(!f_out) {
		if(f_in1 != NULL)
			fclose(f_in1);
		if(f_in2 != NULL)
			fclose(f_in2);
		syslog(LOG_ERR,"File [%s] cannot be opened for write.\n", out);
		return 1;
	}
	char f_out_buffer[32768];
	setvbuf(f_out, f_out_buffer, _IOFBF, 32768);

	wav_write_header(f_out, samplerate, stereo);

	fseek(f_in1, 0, SEEK_END);
	file_size1 = ftell(f_in1);
	fseek(f_in1, 0, SEEK_SET);

	if(in2 != NULL) {
		fseek(f_in2, 0, SEEK_END);
		file_size2 = ftell(f_in2);
		fseek(f_in2, 0, SEEK_SET);
	}

	bitstream_buf1 = new FILE_LINE char[file_size1];
	if(!bitstream_buf1) {
		if(f_in1 != NULL)
			fclose(f_in1);
		if(f_in2 != NULL)
			fclose(f_in2);
		if(f_out != NULL)
			fclose(f_out);
		syslog(LOG_ERR,"Cannot malloc bitsream_buf1[%ld]", file_size1);
		return 1;
	}

	if(in2 != NULL) {
		bitstream_buf2 = new FILE_LINE char[file_size2];
		if(!bitstream_buf2) {
			fclose(f_in1);
			fclose(f_in2);
			fclose(f_out);
			delete [] bitstream_buf1;
			syslog(LOG_ERR,"Cannot malloc bitsream_buf2[%ld]", file_size1);
			return 1;
		}
	}
	fread(bitstream_buf1, file_size1, 1, f_in1);
	p1 = bitstream_buf1;
	f1 = bitstream_buf1 + file_size1;

	if(in2 != NULL) {
		fread(bitstream_buf2, file_size2, 1, f_in2);
		p2 = bitstream_buf2;
		f2 = bitstream_buf2 + file_size2;
	} else {
		p2 = f2 = 0;
	}

	while(p1 < f1 || p2 < f2 ) {
		if(p1 < f1 && p2 < f2) {
			if(stereo) {
			/* stereo */
				if(swap) {
					fwrite(p2, 2, 1, f_out);
					fwrite(p1, 2, 1, f_out);
				} else {
					fwrite(p1, 2, 1, f_out);
					fwrite(p2, 2, 1, f_out);
				}
			} else {
			/* mono */
				slinear_saturated_add((short int*)p1, (short int*)p2);
				fwrite(p1, 2, 1, f_out);
			}
			p1 += 2;
			p2 += 2;
		} else if ( p1 < f1 ) {
			if(swap) {
				if(stereo) {
					fwrite(&zero, 2, 1, f_out);
				}
				fwrite(p1, 2, 1, f_out);
			} else {
				fwrite(p1, 2, 1, f_out);
				if(stereo) {
					fwrite(&zero, 2, 1, f_out);
				}
			}
			p1 += 2;
		} else if ( p2 < f2 ) {
			if(swap) {
				fwrite(p2, 2, 1, f_out);
				if(stereo) {
					fwrite(&zero, 2, 1, f_out);
				}
			} else {
				if(stereo) {
					fwrite(&zero, 2, 1, f_out);
				}
				fwrite(p2, 2, 1, f_out);
			}
			p2 += 2;
		}
	}

	wav_update_header(f_out);
	if(bitstream_buf1)
		delete [] bitstream_buf1;
	if(bitstream_buf2)
		delete [] bitstream_buf2;
	fclose(f_out);
	fclose(f_in1);
	if(f_in2) fclose(f_in2);

	return 0;
}
Exemplo n.º 3
0
int AudioConvertFunc(const char *outfilename,int sample_rate,int channels,int sec,const char *inputfilename,HWND mParentHwnd,UINT mMsg)
{
	AVCodec *aCodec =NULL;
	AVPacket *packet = NULL;
	AVFormatContext *pFormatCtx =NULL;
    AVCodecContext *aCodecCtx= NULL;
	ReSampleContext* ResampleCtx=NULL;
	AVFrame *decoded_frame = NULL;
	int datasize;
	//int tempcount = 0;
	//long total_out_size=0;
	int64_t total_in_convert_size = 0;
	int audioConvertProgress = 0;
	int tempAudioConvertProgress;
	unsigned int i;
	int len, ret, buffer_size, count, audio_stream_index = -1, totle_samplenum = 0;

	FILE *outfile = NULL;// *infile;
	head_pama pt;

	int16_t *audio_buffer = NULL;
	int16_t *resamplebuff = NULL;
	int ResampleChange=0;
	int ChannelsChange=0;
	int tempret;

	packet = (AVPacket*)malloc(sizeof(AVPacket));
	if (packet==NULL)
	{
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)(-1));
		return -1;
	}
	packet->data=NULL;

	buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
	audio_buffer = (int16_t *)av_malloc(buffer_size);
	if (audio_buffer==NULL)
	{
		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)(-2));
		return -2;
	}
	
	av_register_all();

	av_init_packet(packet);
#if 0
	/**********尝试分解av_open_input_file函数*************/
	int ret = 0;
	
	AVFormatParameters ap = { 0 };
	AVDictionary *tmp = NULL;
	AVInputFormat *fmt = NULL;
	AVDictionary **options = NULL;
	if (!pFormatCtx && !(pFormatCtx = avformat_alloc_context()))
		return AVERROR(ENOMEM);
	if (fmt)
		pFormatCtx->iformat = fmt;

	if (options)
		av_dict_copy(&tmp, *options, 0);

	if ((ret = av_opt_set_dict(pFormatCtx, &tmp)) < 0)
		goto fail;
	
	AVDictionary *tmp = NULL;

	if (!pFormatCtx && !(pFormatCtx = avformat_alloc_context()))
		return AVERROR(ENOMEM);

	int ret;
	AVProbeData pd = {inputfilename, NULL, 0};

	if (pFormatCtx->pb) {
		pFormatCtx->flags |= AVFMT_FLAG_CUSTOM_IO;
		if (!pFormatCtx->iformat)
			return av_probe_input_buffer(pFormatCtx->pb, &pFormatCtx->iformat, inputfilename, pFormatCtx, 0, 0);
		else if (pFormatCtx->iformat->flags & AVFMT_NOFILE)
			av_log(pFormatCtx, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
			"will be ignored with AVFMT_NOFILE format.\n");
		return 0;
	}

	if ( (pFormatCtx->iformat && pFormatCtx->iformat->flags & AVFMT_NOFILE) ||
		(!pFormatCtx->iformat && (pFormatCtx->iformat = av_probe_input_format(&pd, 0))))
		return 0;

	URLContext *h;
	int err;

	err = ffurl_open(&h, inputfilename, AVIO_RDONLY);
	if (err < 0)
		return err;
	err = ffio_fdopen(pFormatCtx, h);
	if (err < 0) {
		ffurl_close(h);
		return err;
	}

	if (pFormatCtx->iformat)
		return 0;
	av_probe_input_buffer(pFormatCtx->pb, &pFormatCtx->iformat, inputfilename, pFormatCtx, 0, 0);


	if (pFormatCtx->iformat->flags & AVFMT_NEEDNUMBER) {
		if (!av_filename_number_test(inputfilename)) {
			ret = AVERROR(EINVAL);
			goto fail;
		}
	}

	pFormatCtx->duration = pFormatCtx->start_time = AV_NOPTS_VALUE;
	av_strlcpy(pFormatCtx->filename, inputfilename ? inputfilename : "", sizeof(pFormatCtx->filename));

	/* allocate private data */
	if (pFormatCtx->iformat->priv_data_size > 0) {
		if (!(pFormatCtx->priv_data = av_mallocz(pFormatCtx->iformat->priv_data_size))) {
			ret = AVERROR(ENOMEM);
			goto fail;
		}
		if (pFormatCtx->iformat->priv_class) {
			*(const AVClass**)pFormatCtx->priv_data = pFormatCtx->iformat->priv_class;
			av_opt_set_defaults(pFormatCtx->priv_data);
			if ((ret = av_opt_set_dict(pFormatCtx->priv_data, &tmp)) < 0)
				goto fail;
		}
	}

	/* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
	if (pFormatCtx->pb)
		ff_id3v2_read(pFormatCtx, ID3v2_DEFAULT_MAGIC);

	if (!(pFormatCtx->flags&AVFMT_FLAG_PRIV_OPT) && pFormatCtx->iformat->read_header)
		if ((ret = pFormatCtx->iformat->read_header(pFormatCtx, &ap)) < 0)
			goto fail;

	if (!(pFormatCtx->flags&AVFMT_FLAG_PRIV_OPT) && pFormatCtx->pb && !pFormatCtx->data_offset)
		pFormatCtx->data_offset = avio_tell(pFormatCtx->pb);

	pFormatCtx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;

	if (options) {
		av_dict_free(options);
		*options = tmp;
	}
	return 0;

fail:
	av_dict_free(&tmp);
	if (pFormatCtx->pb && !(pFormatCtx->flags & AVFMT_FLAG_CUSTOM_IO))
		avio_close(pFormatCtx->pb);
	avformat_free_context(pFormatCtx);
	pFormatCtx = NULL;
	return ret;

	return err;
	/**********尝试分解av_open_input_file函数*************/
	//pFormatCtx = avformat_alloc_context();
#endif
	ret = av_open_input_file(&pFormatCtx, inputfilename, NULL,0, NULL);

	if(ret < 0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}
		
		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)1);
		return 1;  
	}

	ret = av_find_stream_info(pFormatCtx);

	if( ret < 0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)2);
		return 2;
	}

	audio_stream_index=-1;
	for(i=0; i< (signed)pFormatCtx->nb_streams; i++)
	{

		if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_stream_index < 0)
		{
			audio_stream_index = i;
			break;
		}
	}

	if(audio_stream_index == -1)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)3);
		return 3;
	}

	aCodecCtx = pFormatCtx->streams[audio_stream_index]->codec;
	if (aCodecCtx==NULL)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)4);
		return 4;
	}
	aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
	if(!aCodec) 
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		/*if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}*/
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)5);
		return 5;
	}
	//resample init
	if (channels==0)
	{
		channels=aCodecCtx->channels;
	}
	if (sample_rate==0)
	{
		sample_rate=aCodecCtx->sample_rate;
	}
	//if (aCodecCtx->channels!=channels)
	//{
	//	ChannelsChange=1;
	//	ResampleChange=1;
	//}
	if (aCodecCtx->sample_rate!=sample_rate||aCodecCtx->channels!=channels)
	{
		ResampleChange=1;
	}
	if (ResampleChange==1)
	{
		ResampleCtx = av_audio_resample_init(channels,aCodecCtx->channels,sample_rate,aCodecCtx->sample_rate,SAMPLE_FMT_S16,SAMPLE_FMT_S16,16,10,0,1.0);
		if (ResampleCtx==NULL)
		{
			if (audio_buffer!=NULL)
			{
				av_free(audio_buffer);
				audio_buffer=NULL;
			}

			if (packet->data!=NULL)
			{
				av_free_packet(packet);
				packet->data=NULL;
			}
			if (packet!=NULL)
			{
				free(packet);
				packet=NULL;
			}
			if (pFormatCtx!=NULL)
			{
				av_close_input_file(pFormatCtx);
				pFormatCtx=NULL;
			}
			/*if (aCodecCtx!=NULL)
			{
				avcodec_close(aCodecCtx);
				aCodecCtx=NULL;
			}*/
			ResampleChange=0;
			PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)6);
			return 6;
		}
		resamplebuff=(int16_t *)malloc(buffer_size);
		if (resamplebuff==NULL)
		{
			if (audio_buffer!=NULL)
			{
				av_free(audio_buffer);
				audio_buffer=NULL;
			}

			if (packet->data!=NULL)
			{
				av_free_packet(packet);
				packet->data=NULL;
			}
			if (packet!=NULL)
			{
				free(packet);
				packet=NULL;
			}
			if (pFormatCtx!=NULL)
			{
				av_close_input_file(pFormatCtx);
				pFormatCtx=NULL;
			}
			/*if (aCodecCtx!=NULL)
			{
				avcodec_close(aCodecCtx);
				aCodecCtx=NULL;
			}*/
			
			if (ResampleChange==1&&ResampleCtx!=NULL)
			{
				audio_resample_close(ResampleCtx);
				ResampleCtx=NULL;
			}
			PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)7);
			return 7;
		}
	}
	//
	datasize=sec*sample_rate;
	if(avcodec_open(aCodecCtx, aCodec)<0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}

		if (ResampleChange==1&&ResampleCtx!=NULL&&resamplebuff!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
			free(resamplebuff);
			resamplebuff=NULL;
		}
		ResampleChange=0;
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)8);
		return 8;
	}

	pt.bits = 16;
	pt.channels = channels;
	pt.rate = sample_rate;

	outfile = fopen(outfilename, "wb");
	if (!outfile) 
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}

		if (ResampleChange==1&&ResampleCtx!=NULL&&resamplebuff!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
			free(resamplebuff);
			resamplebuff=NULL;
		}
		ResampleChange=0;
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)9);
		return 9;
	}

	fseek(outfile,44,SEEK_SET);
    while(av_read_frame(pFormatCtx, packet) >= 0) 
	{
		CheckMessageQueue();
	    if(packet->stream_index == audio_stream_index)
	    {
			//while(packet->size > 0)
			//{
				buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
				len = avcodec_decode_audio3(aCodecCtx, audio_buffer, &buffer_size, packet);

				if (len < 0) 
				{
					break;
				}

				if(buffer_size > 0)
				{
					//resample
					if (ResampleChange==1)
					{
						int samples=buffer_size/ ((aCodecCtx->channels) * 2);
						int resamplenum= 0;
						resamplenum = audio_resample(ResampleCtx, 
							resamplebuff, 
							audio_buffer, 
							samples);
						count = fwrite(resamplebuff, 2*channels, resamplenum, outfile);
					}
					
					else
					{
						count = fwrite(audio_buffer, 2*aCodecCtx->channels, buffer_size/((aCodecCtx->channels)*2), outfile);
					}
					totle_samplenum += count;
				}
				//tempcount++;
				//total_out_size += count*2*aCodecCtx->channels;
				total_in_convert_size += packet->size;
				tempAudioConvertProgress = 100*total_in_convert_size/(pFormatCtx->file_size);
				if(tempAudioConvertProgress != audioConvertProgress)
				{
					if(tempAudioConvertProgress == 100)
						tempAudioConvertProgress = 99;
					audioConvertProgress = tempAudioConvertProgress;
					tempret = PostMessage(mParentHwnd,mMsg,DECING_TAG,audioConvertProgress);
				}
				if (packet->data!=NULL)
				{
					av_free_packet(packet);
					packet->data=NULL;
				}
				//packet->size -= len;
				//packet->data += len;
			//}
			if (datasize!=0&&totle_samplenum>=datasize)
			{
				break;
			}
	    }
	}
	audioConvertProgress = 100;
	PostMessage(mParentHwnd,mMsg,DECING_TAG,audioConvertProgress);
	fseek(outfile,0,SEEK_SET);
	wav_write_header(outfile, pt, totle_samplenum);
	
	if (outfile!=NULL)
	{
		fclose(outfile);
		outfile=NULL;
	}
    
	if (audio_buffer!=NULL)
	{
		av_free(audio_buffer);
		audio_buffer=NULL;
	}
	
	if (aCodecCtx!=NULL)
	{
		avcodec_close(aCodecCtx);
		aCodecCtx=NULL;
	}
	
	if (packet!=NULL)
	{
		free(packet);//
		packet=NULL;
	}
	
	if (pFormatCtx!=NULL)
	{
		av_close_input_file(pFormatCtx);
		pFormatCtx=NULL;
	}
	
	if (ResampleChange==1)
	{
		if (resamplebuff!=NULL)
		{
			free(resamplebuff);
			resamplebuff=NULL;
		}
		if (ResampleCtx!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
		}
	}
	if (totle_samplenum<=sample_rate*5)
	{
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)10);
		return 10;
	}
	PostMessage(mParentHwnd,mMsg,FINISH_TAG,NULL);
	return 0;
}
Exemplo n.º 4
0
int main(int argc, char **argv)
{
	struct tap tapfile;
	struct wav wavfile;
	FILE *infile;
	long pulse;
	long i;
	fixedpoint len, accum;
	long channels[2];
	int wave[2];
	int sample;
	
	getopts(argc, argv);
	if (invert) {
		wave[0] = LOW;
		wave[1] = HIGH;
	} else {
		wave[0] = HIGH;
		wave[1] = LOW;
	}
	
	if (optind == argc) {
		infile = stdin;
	} else if (optind == argc - 1) {
		if (!strcmp(argv[optind], "-")) {
			infile = stdin;
		} else {
			infile = fopen(argv[optind], "rb");
			if (!infile) {
				perror(argv[optind]);
				return 1;
			}
		}
	} else {
		fprintf(stderr, "%s: too many arguments\n", argv0);
		usage();
		return 1;
	}
	if (tap_read_header(&tapfile, infile)) {
		fprintf(stderr, "%s: error reading TAP file\n", argv0);
		return 1;
	}
	wavfile.SampleRate = samplerate;
	wavfile.BitsPerSample = 8;
	wavfile.NumChannels = 1;
	if (wav_write_header(&wavfile, stdout)) {
		fprintf(stderr, "%s: error writing WAV file\n", argv0);
		return 1;
	}
	filter_init(&lowpass_filter, lowpass_freq, wavfile.SampleRate);
#if 0
	/* put one initial sample so the first pulse is recognized */
	channels[0] = wave[1];
	wav_put_sample(&wavfile, channels);
	accum = TO_FIXED(1.5);
#else
	accum = TO_FIXED(2);
#endif
	while ((pulse = tap_get_pulse(&tapfile)) >= 0) {
		//fprintf(stderr, "pulse: %6ld (%04lx)\n", pulse, pulse);
		//if (pulse < 8*256)
			//++pulsehist[pulse/8];
		len = TO_FIXED(((double)pulse * samplerate / PAL_MHZ / speed / 1000000));

		if (len < TO_FIXED(2)) {
			fprintf(stderr, "%s: warning: pulse length (%ld) is less than 2 samples\n", argv0, pulse);
		}
#if 0
		accum = FIXED_F(len + accum);
#else
		len += accum;
		accum = FIXED_F(len);
#endif
#if 0
		fprintf(stderr, "%ld.%03ld 0.%03ld \n",
		        FIXED_I(len),
		        FIXED_F(len) * 1000 / FIXED_ONE,
		        FIXED_F(accum) * 1000 / FIXED_ONE);
#endif
		
		for (i = 0; i < FIXED_I(len) / 2 - 1; ++i) {
			channels[0] = filter_lowpass(&lowpass_filter, wave[0]) << 16;
			wav_put_sample(&wavfile, channels);
		}
		
		for (; i < FIXED_I(len) - 2; ++i) {
			channels[0] = filter_lowpass(&lowpass_filter, wave[1]) << 16;
			wav_put_sample(&wavfile, channels);
		}
#if 0
		channels[0] = FIXED_MUL(wave[1], accum) +
		              FIXED_MUL(wave[0], FIXED_ONE - accum);
		wav_put_sample(&wavfile, channels);
#else
		sample = FIXED_MUL(wave[1], accum);
		channels[0] = filter_lowpass(&lowpass_filter, sample) << 16;
		wav_put_sample(&wavfile, channels);
		sample -= wave[1];
		channels[0] = filter_lowpass(&lowpass_filter, sample) << 16;
		wav_put_sample(&wavfile, channels);
#endif
	}
	wav_close(&wavfile);
	return 0;
}
Exemplo n.º 5
0
//The recording stuff runs in its own thread
//this prevents dropouts in the recording in case the
//bandwidth is smaller than the selected streaming bitrate
void* snd_rec_thread(void *data)
{
    int rb_bytes_read;
    int bytes_to_read;
    int ogg_header_written;
    int opus_header_written;
    int enc_bytes_read;
    
    char *enc_buf = (char*)malloc(rec_rb.size * sizeof(char)*10);
    char *audio_buf = (char*)malloc(rec_rb.size * sizeof(char)*10);

    ogg_header_written = 0;
    opus_header_written = 0;

    while(record)
    {
        pthread_cond_wait(&rec_cond, &rec_mut);

        if(next_file == 1)
        {
            if(!strcmp(cfg.rec.codec, "flac")) // The flac encoder closes the file
                flac_enc_close(&flac_rec);
            else
                fclose(cfg.rec.fd);

            cfg.rec.fd = next_fd;
            next_file = 0;
            if(!strcmp(cfg.rec.codec, "ogg"))
            {
                vorbis_enc_reinit(&vorbis_rec);
                ogg_header_written = 0;
            }
            if(!strcmp(cfg.rec.codec, "opus"))
            {
                opus_enc_reinit(&opus_rec);
                opus_header_written = 0;
            }
            if(!strcmp(cfg.rec.codec, "flac"))
            {
                flac_enc_reinit(&flac_rec);
                flac_enc_init_FILE(&flac_rec, cfg.rec.fd);
            }
        }

        // Opus needs a special treatment
        // The encoder needs a predefined count of frames
        // Therefore we don't feed the encoder with all data we have in the
        // ringbuffer at once 
        if(!strcmp(cfg.rec.codec, "opus"))
        {
            bytes_to_read = 960 * sizeof(short)*cfg.audio.channel;
            while ((rb_filled(&rec_rb)) >= bytes_to_read)
            {
                rb_read_len(&rec_rb, audio_buf, bytes_to_read);

                if(!opus_header_written)
                {
                    opus_enc_write_header(&opus_rec);
                    opus_header_written = 1;
                }

                enc_bytes_read = opus_enc_encode(&opus_rec, (short*)audio_buf, 
                        enc_buf, bytes_to_read/(2*cfg.audio.channel));
                kbytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd)/1024.0;
            }
        }
        else
        {

            if(rb_filled(&rec_rb) < framepacket_size*sizeof(short))
                continue;

            rb_bytes_read = rb_read(&rec_rb, audio_buf);
            if(rb_bytes_read == 0)
                continue;


            if(!strcmp(cfg.rec.codec, "mp3"))
            {

                enc_bytes_read = lame_enc_encode(&lame_rec, (short*)audio_buf, enc_buf,
                        rb_bytes_read/(2*cfg.audio.channel), rec_rb.size*10);
                kbytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd)/1024.0;
            }

            if(!strcmp(cfg.rec.codec, "ogg"))
            {
                if(!ogg_header_written)
                {
                    vorbis_enc_write_header(&vorbis_rec);
                    ogg_header_written = 1;
                }

                enc_bytes_read = vorbis_enc_encode(&vorbis_rec, (short*)audio_buf, 
                        enc_buf, rb_bytes_read/(2*cfg.audio.channel));
                kbytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd)/1024.0;
            }

            if(!strcmp(cfg.rec.codec, "flac"))
            {
                flac_enc_encode(&flac_rec, (short*)audio_buf, rb_bytes_read/sizeof(short)/cfg.audio.channel, cfg.audio.channel);
                kbytes_written = flac_enc_get_bytes_written()/1024.0;
            }


            if(!strcmp(cfg.rec.codec, "wav"))
            {
                //this permanently updates the filesize value in the WAV header
                //so we still have a valid WAV file in case of a crash
                wav_write_header(cfg.rec.fd, cfg.audio.channel, cfg.audio.samplerate, 16);
                kbytes_written += fwrite(audio_buf, sizeof(char), rb_bytes_read, cfg.rec.fd)/1024.0;
            }

            if(!strcmp(cfg.rec.codec, "aac")) {
                enc_bytes_read = aac_enc_encode(&aac_rec, (short*) audio_buf, enc_buf, rb_bytes_read / (2*cfg.audio.channel), cfg.audio.channel);
                kbytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd) / 1024.0;
            }
        }
    }

    if(!strcmp(cfg.rec.codec, "flac")) // The flac encoder closes the file
        flac_enc_close(&flac_rec);
    else
        fclose(cfg.rec.fd);
    
    free(enc_buf);
    free(audio_buf);
    
    return NULL;
}
Exemplo n.º 6
0
void extract_wavs_from_drm(char * name)
{
	FILE * drmfile;
	FILE * wavfile;
	size_t len;

	unsigned int version;
	unsigned int count;

	char * destdir = create_output_dir(name);
	if (!destdir) {
		fprintf(stderr, "Error creating output directory for file %s.\n", name);
		return;
	}

	if (fopen_s(&drmfile, name, "rb")) {
		fprintf(stderr, "Error opening file %s.\n", name);
		free(destdir);
		return;
	}

	len = fread(&version, sizeof(version), 1, drmfile);
	if (len != 1)
		goto read_err;

	if (version != 14) {
		fprintf(stderr, "DRM version 0x%02x is not supported.\n", version);
		goto bail;
	}

	len = fread(&count, sizeof(count), 1, drmfile);
	if (len != 1)
		goto read_err;

	struct ste * section_table = calloc(count, sizeof(struct ste));
	if (!section_table) {
		fprintf(stderr, "Error allocating section table.\n");
		goto bail;
	}

	len = fread((void *)section_table, sizeof(struct ste), count, drmfile);
	if (len != count)
		goto read_err;

	for (unsigned int i = 0; i < count; i++) {
		if (section_table[i].type != audio) {
			fseek(drmfile, (section_table[i].hdrlen * 8) + section_table[i].datalen, SEEK_CUR);
			continue;
		}
		
		char wavname[1024] = {0};
		if (_snprintf_s(wavname, 1024, _TRUNCATE, "%s/%u.wav", destdir, section_table[i].id) == -1) {
			fprintf(stderr, "Error printing wav file name.\n");
			goto bail;
		}
		if (fopen_s(&wavfile, wavname, "wb")) {
			fprintf(stderr, "Error creating wav file %s.\n", wavname);
			goto bail;
		}

		/* Leave space for the WAV header */
		wav_skip_header(wavfile);

		/* Prepare DRM file */
		fseek(drmfile, (section_table[i].hdrlen * 8), SEEK_CUR);

		unsigned int freq;
		len = fread(&freq, sizeof(freq), 1, drmfile);
		if (len != 1)
			goto read_err;

		/* Skip over loop points */
		fseek(drmfile, 8, SEEK_CUR);

		if (xcs(drmfile, wavfile, section_table[i].datalen - 12) < 0)
			fprintf(stderr, "Error converting audio section %d.\n", i);

		/* Write WAV header */
		unsigned int extract_size = ((section_table[i].datalen - 12) / 36) * 128;
		wav_write_header(wavfile, extract_size, 1, freq, 16);

		fclose(wavfile);
	}

bail:
	free(destdir);
	fclose(drmfile);
	return;

read_err:
	fprintf(stderr, "Read error in file %s.\n", name);
	free(destdir);
	fclose(drmfile);
	return;
}