示例#1
0
krad_transmission_t *krad_transmitter_transmission_create (krad_transmitter_t *krad_transmitter, char *name, char *content_type) {

    int t;

    t = 0;
    for (t = 0; t < DEFAULT_MAX_TRANSMISSIONS; t++) {
        if (krad_transmitter->krad_transmissions[t].active == 0) {
            krad_transmitter->krad_transmissions[t].active = 2;
            krad_transmitter->krad_transmissions[t].ready_receivers = NULL;
            krad_transmitter->krad_transmissions[t].ready_receiver_count = 0;
            krad_transmitter->krad_transmissions[t].ready = 0;
            krad_transmitter->krad_transmissions[t].position = 0;
            krad_transmitter->krad_transmissions[t].sync_point = -1;
            strcpy (krad_transmitter->krad_transmissions[t].sysname, name);
            strcpy (krad_transmitter->krad_transmissions[t].content_type, content_type);

            krad_transmitter->krad_transmissions[t].http_header_len = sprintf (krad_transmitter->krad_transmissions[t].http_header,
                    "HTTP/1.0 200 OK\r\nContent-Type: %s\r\nServer: %s\r\n"
                    "Cache-Control: no-cache\r\n\r\n",
                    krad_transmitter->krad_transmissions[t].content_type,
                    KRAD_TRANSMITTER_SERVER
                                                                              );

            printk ("Krad Transmitter: http header for %s is %d bytes: %s",
                    krad_transmitter->krad_transmissions[t].sysname,
                    krad_transmitter->krad_transmissions[t].http_header_len,
                    krad_transmitter->krad_transmissions[t].http_header);

            krad_transmitter->krad_transmissions[t].connections_efd = epoll_create (0);
            krad_transmitter->krad_transmissions[t].transmission_events = calloc (KRAD_TRANSMITTER_MAXEVENTS, sizeof (struct epoll_event));
            krad_transmitter->krad_transmissions[t].ringbuffer = krad_ringbuffer_create (DEFAULT_RING_SIZE);

            if (krad_transmitter->krad_transmissions[t].ringbuffer == NULL) {
                failfast ("Krad Transmitter: Out of memory creating new transmission");
            }

            krad_transmitter->krad_transmissions[t].transmission_ringbuffer = krad_ringbuffer_create (DEFAULT_RING_SIZE);

            if (krad_transmitter->krad_transmissions[t].transmission_ringbuffer == NULL) {
                failfast ("Krad Transmitter: Out of memory creating new transmission");
            }

            krad_transmitter->krad_transmissions[t].transmission_buffer = calloc (1, DEFAULT_RING_SIZE);

            if (krad_transmitter->krad_transmissions[t].transmission_buffer == NULL) {
                failfast ("Krad Transmitter: Out of memory creating new transmission");
            }

            pthread_create (&krad_transmitter->krad_transmissions[t].transmission_thread, NULL, krad_transmitter_transmission_thread, (void *)&krad_transmitter->krad_transmissions[t]);

            krad_transmitter->krad_transmissions[t].active = 1;
            return &krad_transmitter->krad_transmissions[t];
        }
    }

    return NULL;

}
示例#2
0
void audio_encoding_unit_create (void *arg) {

  //krad_system_set_thread_name ("kr_audio_enc");

  krad_link_t *krad_link = (krad_link_t *)arg;

  int c;

  printk ("Audio unit create");

  if (krad_link->codec != VORBIS) {
    krad_link->au_buffer = malloc (300000);
  }

  krad_link->au_interleaved_samples = malloc (8192 * 4 * KR_MXR_MAX_CHANNELS);

  for (c = 0; c < krad_link->channels; c++) {
    krad_link->au_samples[c] = malloc (8192 * 4);
    krad_link->samples[c] = malloc (8192 * 4);
    krad_link->audio_input_ringbuffer[c] = krad_ringbuffer_create (2000000);
  }

  if (socketpair(AF_UNIX, SOCK_STREAM, 0, krad_link->socketpair)) {
    printk ("Krad Compositor: subunit could not create socketpair errno: %d", errno);
    return;
  }

//  krad_link->mixer_portgroup = kr_mixer_path_create(krad_link->krad_radio->mixer,
//   krad_link->sysname, KR_AOUT, 0, krad_link->channels, 0.0f,
//   krad_link->krad_radio->mixer->master, 0, krad_link, 0);

  switch (krad_link->codec) {
    case VORBIS:
      krad_link->krad_vorbis = krad_vorbis_encoder_create (krad_link->channels,
                                 krad_link->krad_radio->mixer->sample_rate,
                                 krad_link->vorbis_quality);
      //krad_link->au_framecnt = KRAD_DEFAULT_VORBIS_FRAME_SIZE;
      break;
    case FLAC:
      krad_link->krad_flac = krad_flac_encoder_create (krad_link->channels,
                               krad_link->krad_radio->mixer->sample_rate,
                               krad_link->flac_bit_depth);
      krad_link->au_framecnt = KRAD_DEFAULT_FLAC_FRAME_SIZE;
      break;
    case OPUS:
      krad_link->krad_opus = krad_opus_encoder_create (krad_link->channels,
                               krad_link->krad_radio->mixer->sample_rate,
                               krad_link->opus_bitrate,
                               OPUS_APPLICATION_AUDIO);
      krad_link->au_framecnt = KRAD_MIN_OPUS_FRAME_SIZE;
      break;
    default:
      failfast ("Krad Link Audio Encoder: Unknown Audio Codec");
  }
  krad_link->audio_encoder_ready = 1;
}
int main (int argc, char *argv[]) {

	krad_v4l2_vpx_display_test_t *display_test;
	krad_flac_t *krad_flac;
	krad_dirac_t *krad_dirac;
	krad_vpx_encoder_t *krad_vpx_encoder;
	//krad_vpx_decoder_t *krad_vpx_decoder;
	kradgui_t *kradgui;
	kradebml_t *ebml;
	cairo_surface_t *cst;
	cairo_t *cr;
	char *filename = "/home/oneman/kode/testmedia/capture/new_testfile4.webm";
	int hud_width, hud_height;
	int hud_stride;
	int hud_byte_size;
	unsigned char *hud_data;
	struct SwsContext *sws_context;

	int fps;

	int videotrack;
	int audiotrack;
	char *device;
	krad_v4l2_t *kradv4l2;
	krad_sdl_opengl_display_t *krad_opengl_display;
	int width;
	int height;
	int count;
	//int first_frame;
	int read_composited;
	
	unsigned char *read_screen_buffer;
	unsigned char *dbuffer;
	unsigned char *dfbuffer;
	krad_audio_t *audio;
	krad_audio_api_t audio_api;
	krad_vorbis_t *krad_vorbis;
	
	hud_width = 320;
	hud_height = 240;

	read_composited = 1;
	//first_frame = 1;
	
	width = 640;
	height = 480;
	fps = 30;
	count = 0;
	int keyframe;
	int bitrate;
	void *frame = NULL;
	void *vpx_packet;
	int packet_size;
	int took;
	int video_codec;
	int audio_codec;
	int framenum;
	int bytes;
	
	bitrate = 1000;
	
	video_codec = 1;
	audio_codec = 1;
		
	if (argc < 2) {
		device = DEFAULT_DEVICE;
		printf("no device provided, using %s , to provide a device, example: krad_v4l2_test /dev/video0\n", device);
	} else {
		device = argv[1];
		printf("Using %s\n", device);
	}

	display_test = calloc(1, sizeof(krad_v4l2_vpx_display_test_t));
	pthread_rwlock_init(&display_test->ebml_write_lock, NULL);
	pthread_rwlock_rdlock(&display_test->ebml_write_lock);
	//display_test->kradtimer = kradtimer_create();
	display_test->input_ringbuffer[0] = krad_ringbuffer_create (RINGBUFFER_SIZE);
	display_test->input_ringbuffer[1] = krad_ringbuffer_create (RINGBUFFER_SIZE);
	display_test->samples[0] = malloc(4 * 8192);
	display_test->samples[1] = malloc(4 * 8192);
	display_test->first_block = 1;
	display_test->audio_codec = audio_codec;
	
	dbuffer = calloc(1, 2000000);
	dfbuffer = calloc(1, 2000000);
	audio_api = JACK;
	//audio = kradaudio_create("krad v4l2 vpx display test", audio_api);
	krad_vorbis = krad_vorbis_encoder_create(2, 44100, 0.7);
	krad_flac = krad_flac_encoder_create(1, 44100, 16);
	
	read_screen_buffer = calloc(1, width * height * 4 * 4 * 4 * 4);
	sws_context = sws_getContext ( width, height, PIX_FMT_RGB32, width, height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
	ebml = kradebml_create();
	//kradebml_open_output_stream(ebml, "192.168.1.2", 9080, "/teststream.webm", "secretkode");
	kradebml_open_output_file(ebml, filename);
	if (video_codec == 1) {
		kradebml_header(ebml, "webm", APPVERSION);
	} else {
		kradebml_header(ebml, "matroska", APPVERSION);
	}
	if (video_codec == 1) {
		videotrack = kradebml_add_video_track(ebml, "V_VP8", 30, width, height);
	}
	if (video_codec == 2) {
		videotrack = kradebml_add_video_track(ebml, "V_DIRAC", 10, width, height);
	}
	if (audio_codec == 1) {
		audiotrack = kradebml_add_audio_track(ebml, "A_VORBIS", 44100, 2, krad_vorbis->header, krad_vorbis->headerpos);
	}
	if (audio_codec == 2) {
		bytes = krad_flac_encoder_read_min_header(krad_flac, dfbuffer);
		audiotrack = kradebml_add_audio_track(ebml, "A_FLAC", 44100, 1, dfbuffer, bytes);
		display_test->krad_flac = krad_flac;
	}	
	kradebml_write(ebml);

	krad_opengl_display = krad_sdl_opengl_display_create(APPVERSION, width, height, width, height);
	//krad_opengl_display = krad_sdl_opengl_display_create(APPVERSION, 1920, 1080, width, height);
	
	krad_vpx_encoder = krad_vpx_encoder_create(width, height, bitrate);
	krad_dirac = krad_dirac_encoder_create(width, height);
	kradgui = kradgui_create(width, height);
	kradgui_add_item(kradgui, REEL_TO_REEL);
	
	hud_stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, hud_width);
	hud_byte_size = hud_stride * hud_height;
	hud_data = calloc (1, hud_byte_size);
	cst = cairo_image_surface_create_for_data (hud_data, CAIRO_FORMAT_ARGB32, hud_width, hud_height, hud_stride);
	
	krad_opengl_display->hud_width = hud_width;
	krad_opengl_display->hud_height = hud_height;
	krad_opengl_display->hud_data = hud_data;
	display_test->audiotrack = audiotrack;
	display_test->ebml = ebml;
	//display_test->audio = audio;
	display_test->krad_vorbis = krad_vorbis;
	display_test->kradgui = kradgui;

	kradv4l2 = kradv4l2_create();

	kradv4l2_open(kradv4l2, device, width, height, fps);
	
	kradv4l2_start_capturing (kradv4l2);
	
	kradgui_reset_elapsed_time(kradgui);
	kradgui->render_timecode = 1;
	
	audio = kradaudio_create("krad v4l2 vpx display test", KINPUT, audio_api);
	display_test->audio = audio;
	pthread_create(&display_test->audio_encoding_thread, NULL, audio_encoding_thread, (void *)display_test);
	
	kradaudio_set_process_callback(audio, krad_v4l2_vpx_display_test_audio_callback, display_test);
	if (audio_api == JACK) {
		krad_jack_t *jack = (krad_jack_t *)audio->api;
		kradjack_connect_port(jack->jack_client, "firewire_pcm:001486af2e61ac6b_Unknown0_in", "krad v4l2 vpx display test:InputLeft");
		kradjack_connect_port(jack->jack_client, "firewire_pcm:001486af2e61ac6b_Unknown0_in", "krad v4l2 vpx display test:InputRight");
	}
	while (count < TEST_COUNT) {
		//kradtimer_start(display_test->kradtimer, "cycle");


		cr = cairo_create(cst);
		kradgui->cr = cr;
		kradgui_render(kradgui);
		cairo_destroy(cr);
		
		frame = kradv4l2_read_frame_wait (kradv4l2);
		
		if (display_test->start_audio == 0) {
			display_test->start_audio = 1;
			usleep(200000);
		}
		
		if (video_codec == 2) {
		//	memcpy(dfbuffer, frame, width * height + (((width * height) / 2) * 2));
		}
		krad_vpx_convert_uyvy2yv12(krad_vpx_encoder->image, frame, width, height);
		///krad_vpx_convert_frame_for_local_gl_display(krad_vpx_encoder);
		kradv4l2_frame_done (kradv4l2);
		
		
		
		krad_sdl_opengl_display_render(krad_opengl_display, krad_vpx_encoder->image->planes[0], krad_vpx_encoder->image->stride[0], krad_vpx_encoder->image->planes[1], krad_vpx_encoder->image->stride[1], krad_vpx_encoder->image->planes[2], krad_vpx_encoder->image->stride[2]);

		krad_sdl_opengl_draw_screen( krad_opengl_display );
		
		if (read_composited) {
			krad_sdl_opengl_read_screen( krad_opengl_display, read_screen_buffer);
			rgb_to_yv12(sws_context, read_screen_buffer, width, height, krad_vpx_encoder->image->planes, krad_vpx_encoder->image->stride);
			vpx_img_flip(krad_vpx_encoder->image);
		}
		
		if (video_codec == 1) {
		
			count++;
		
			packet_size = krad_vpx_encoder_write(krad_vpx_encoder, (unsigned char **)&vpx_packet, &keyframe);

			//printf("packet size was %d\n", packet_size);
			if (read_composited) {
				vpx_img_flip(krad_vpx_encoder->image);
			}
		
			if (packet_size) {
				pthread_rwlock_wrlock(&display_test->ebml_write_lock);
				kradebml_add_video(ebml, videotrack, vpx_packet, packet_size, keyframe);
				//kradebml_write(ebml);
				pthread_rwlock_unlock (&display_test->ebml_write_lock);		
			}


		}
		
		
		if (video_codec == 2) {

//			packet_size = krad_dirac_encode (krad_dirac, dfbuffer, dbuffer, &framenum, &took);
			packet_size = krad_dirac_encode (krad_dirac, krad_vpx_encoder->image->img_data, dbuffer, &framenum, &took);
			if (took == 1) {
				took = 0;
				count++;
			}
	
			if (packet_size > 0) {
				krad_dirac_packet_type(dbuffer[4]);
				//write(fd, buffer, len);
				printf("Encoded size is %d for frame %d\n", packet_size, framenum);
			}
		
			//printf("packet size was %d\n", packet_size);
			if (read_composited) {
				vpx_img_flip(krad_vpx_encoder->image);
			}
		
			keyframe = 0;
		
			if (packet_size) {
				pthread_rwlock_wrlock(&display_test->ebml_write_lock);
				kradebml_add_video(ebml, videotrack, dbuffer, packet_size, keyframe);
				//kradebml_write(ebml);
				pthread_rwlock_unlock (&display_test->ebml_write_lock);		
			}
		
		}
		
	//kradtimer_finish_show(display_test->kradtimer);
	}
	
	display_test->start_audio = 0;
	
	if (video_codec == 2) {
		
		schro_encoder_end_of_stream (krad_dirac->encoder);
//			packet_size = krad_dirac_encode (krad_dirac, dfbuffer, dbuffer, &framenum, &took);

		while ((framenum != count - 1) && (framenum != 0)) {

			packet_size = krad_dirac_encode (krad_dirac, krad_vpx_encoder->image->img_data, dbuffer, &framenum, &took);

			if (packet_size > 0) {
				krad_dirac_packet_type(dbuffer[4]);
				//write(fd, buffer, len);
				printf("Encoded size is %d for frame %d\n", packet_size, framenum);
			} else {
				usleep(50000);
			}
	
			//printf("packet size was %d\n", packet_size);
			if (read_composited) {
				//vpx_img_flip(krad_vpx_encoder->image);
			}
	
			keyframe = 0;
	
			if (packet_size) {
				pthread_rwlock_wrlock(&display_test->ebml_write_lock);
				kradebml_add_video(ebml, videotrack, dbuffer, packet_size, keyframe);
				//kradebml_write(ebml);
				pthread_rwlock_unlock (&display_test->ebml_write_lock);		
			}
	
		}
	
	}
	

	//display_test->start_audio = 0;
	printf("finish audio encoding\n");
	usleep(2000000);
	display_test->stop_audio_encoding = 1;
	
	
	pthread_join(display_test->audio_encoding_thread, NULL);
	
	kradebml_destroy(ebml);

	kradv4l2_stop_capturing (kradv4l2);

	kradv4l2_close(kradv4l2);

	kradv4l2_destroy(kradv4l2);
	krad_dirac_encoder_destroy(krad_dirac);
	krad_vpx_encoder_destroy(krad_vpx_encoder);
	
	// must be before vorbis
	kradaudio_destroy(audio);
	
	krad_vorbis_encoder_destroy(krad_vorbis);
	krad_flac_encoder_destroy(krad_flac);
	free(display_test->samples[0]);
	free(display_test->samples[1]);
	
	krad_sdl_opengl_display_destroy(krad_opengl_display);
	kradgui_destroy(kradgui);
	
	free(read_screen_buffer);
	sws_freeContext (sws_context);
	
	krad_ringbuffer_free ( display_test->input_ringbuffer[0] );
	krad_ringbuffer_free ( display_test->input_ringbuffer[1] );
	pthread_rwlock_destroy(&display_test->ebml_write_lock);
	//kradtimer_destroy(display_test->kradtimer);
	free(display_test);
	free(dbuffer);
	free(dfbuffer);
	return 0;

}
示例#4
0
kr_streamer_t *kr_streamer_create (kr_streamer_params_t *params) {

  kr_streamer_t *streamer;
  uint32_t c;

  streamer = calloc (1, sizeof(kr_streamer_t));

  streamer->params = params;

  streamer->params->channels = 2;
  streamer->params->sample_rate = 48000;

  streamer->client = kr_client_create ("krad streamer client");

  if (streamer->client == NULL) {
    fprintf (stderr, "Could not create KR client.\n");
    exit (1);
  }

  kr_connect (streamer->client, streamer->params->station);

  if (!kr_connected (streamer->client)) {
    fprintf (stderr, "Could not connect to %s krad radio daemon.\n",
             streamer->params->station);
    kr_client_destroy (&streamer->client);
    exit (1);
  }

  if (kr_compositor_get_info_wait (streamer->client,
                                   &streamer->width, &streamer->height,
                                   &streamer->fps_numerator, &streamer->fps_denominator) != 1) {
    fprintf (stderr, "Could not get compositor info!\n");
    kr_client_destroy (&streamer->client);
    exit (1);
  }

  streamer->frame_size = streamer->width * streamer->height * 4;
  //FIXME
  streamer->videoport = kr_videoport_create (streamer->client, 0);

  if (streamer->videoport == NULL) {
    fprintf (stderr, "Could not make videoport.\n");
    kr_client_destroy (&streamer->client);
    exit (1);
  } else {
    printf ("Working!\n");
  }

  kr_videoport_set_callback (streamer->videoport, new_frame, streamer);

  for (c = 0; c < streamer->params->channels; c++) {
    streamer->audio_ring[c] = krad_ringbuffer_create (2200000);
  }

  if (params->file != NULL) {
    streamer->mkv = kr_mkv_create_file (params->file);
  } else {
    streamer->mkv = kr_mkv_create_stream (streamer->params->host,
                                      streamer->params->port,
                                      streamer->params->mount,
                                      streamer->params->password);
  }

  if (streamer->mkv == NULL) {
    fprintf (stderr, "failed to stream :/ \n");
    exit (1);
  }

  streamer->vpx_enc = krad_vpx_encoder_create (streamer->params->width,
                                           streamer->params->height,
                                           streamer->fps_numerator,
                                           streamer->fps_denominator,
                                           streamer->params->video_bitrate);

  if (params->file != NULL) {
    krad_vpx_encoder_set_kf_max_dist (streamer->vpx_enc, 600);
  }

  kr_mkv_add_video_track (streamer->mkv, VP8,
                          streamer->fps_numerator,
                          streamer->fps_denominator,
                          streamer->params->width,
                          streamer->params->height);

  if (kr_mixer_get_info_wait (streamer->client, &streamer->params->sample_rate, NULL) != 1) {
    fprintf (stderr, "Could not get mixer info!\n");
    kr_client_destroy (&streamer->client);
    exit (1);
  }

  streamer->vorbis_enc = krad_vorbis_encoder_create (streamer->params->channels,
                                                     streamer->params->sample_rate,
                                                     streamer->params->audio_quality);

  kr_mkv_add_audio_track (streamer->mkv, VORBIS, streamer->params->sample_rate,
                          streamer->params->channels,
                          streamer->vorbis_enc->hdrdata,
                          3 +
                          streamer->vorbis_enc->header.sz[0] +
                          streamer->vorbis_enc->header.sz[1] +
                          streamer->vorbis_enc->header.sz[2]);
  //FIXME
  streamer->audioport = kr_audioport_create (streamer->client, "streamer2",
   0);
  kr_audioport_set_callback (streamer->audioport, audioport_process, streamer);

  streamer->frame_ring = krad_ringbuffer_create (90 * sizeof(krad_frame_t *));

  streamer->framepool = krad_framepool_create (streamer->width,
                                               streamer->height,
                                               8);

  return streamer;
}
示例#5
0
krad_opus_t *krad_opus_decoder_create (unsigned char *header_data, int header_length, float output_sample_rate) {

	int c;

	krad_opus_t *krad_opus = calloc (1, sizeof(krad_opus_t));

	krad_opus->output_sample_rate = output_sample_rate;

	krad_opus->opus_header = calloc (1, sizeof(OpusHeader));
	
	if (opus_header_parse (header_data, header_length, krad_opus->opus_header) != 1) {
		failfast ("krad_opus_decoder_create problem reading opus header");	
	}

	// oops
	//krad_opus->input_sample_rate = krad_opus->opus_header->input_sample_rate;

	krad_opus->channels = krad_opus->opus_header->channels;

	krad_opus->interleaved_samples = malloc(16 * 8192);
	
	for (c = 0; c < krad_opus->channels; c++) {
		krad_opus->ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->resampled_ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->samples[c] = malloc (16 * 8192);
		krad_opus->read_samples[c] = malloc (16 * 8192);
		krad_opus->resampled_samples[c] = malloc (16 * 8192);

		krad_opus->src_resampler[c] = src_new (KRAD_OPUS_SRC_QUALITY, 1, &krad_opus->src_error[c]);
		if (krad_opus->src_resampler[c] == NULL) {
			failfast ("krad_opus_decoder_create src resampler error: %s", src_strerror (krad_opus->src_error[c]));
		}
	
		krad_opus->src_data[c].src_ratio = output_sample_rate / 48000;
	
		printk ("krad_opus_decoder_create src resampler ratio is: %f", krad_opus->src_data[c].src_ratio);	

	}

	krad_opus->streams = krad_opus->opus_header->nb_streams;
	krad_opus->coupled_streams = krad_opus->opus_header->nb_coupled;

	memcpy (krad_opus->mapping, krad_opus->opus_header->stream_map, 256);

	printk ("krad_opus_decoder_create channels %d streams %d coupled %d",
			krad_opus->channels,
			krad_opus->streams,
			krad_opus->coupled_streams
			);	

	krad_opus->decoder = opus_multistream_decoder_create (48000,
														  krad_opus->opus_header->channels,
														  krad_opus->streams,
														  krad_opus->coupled_streams,
														  krad_opus->mapping,
														  &krad_opus->opus_decoder_error);
	if (krad_opus->opus_decoder_error != OPUS_OK) {
		failfast ("Cannot create decoder: %s", opus_strerror (krad_opus->opus_decoder_error));
	}

	return krad_opus;

}
示例#6
0
krad_opus_t *krad_opus_encoder_create (int channels, int input_sample_rate, int bitrate, int application) {

	int c;

	krad_opus_t *krad_opus = calloc(1, sizeof(krad_opus_t));

	krad_opus->opus_header = calloc(1, sizeof(OpusHeader));

	krad_opus->input_sample_rate = input_sample_rate;
	krad_opus->channels = channels;
	krad_opus->bitrate = bitrate;
	krad_opus->application = application;
	krad_opus->complexity = DEFAULT_OPUS_COMPLEXITY;
	krad_opus->signal = OPUS_AUTO;
	krad_opus->frame_size = DEFAULT_OPUS_FRAME_SIZE;
	krad_opus->bandwidth = OPUS_BANDWIDTH_FULLBAND;

	krad_opus->new_frame_size = krad_opus->frame_size;
	krad_opus->new_complexity = krad_opus->complexity;
	krad_opus->new_bitrate = krad_opus->bitrate;
	krad_opus->new_signal = krad_opus->signal;
	krad_opus->new_bandwidth = krad_opus->bandwidth;
	
	for (c = 0; c < krad_opus->channels; c++) {
		krad_opus->ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->resampled_ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->samples[c] = malloc(16 * 8192);
		krad_opus->resampled_samples[c] = malloc(16 * 8192);
		krad_opus->src_resampler[c] = src_new (KRAD_OPUS_SRC_QUALITY, 1, &krad_opus->src_error[c]);
		if (krad_opus->src_resampler[c] == NULL) {
			failfast ("Krad Opus Encoder: src resampler error: %s", src_strerror (krad_opus->src_error[c]));
		}
		
		krad_opus->src_data[c].src_ratio = 48000.0 / krad_opus->input_sample_rate;
	}

	if (krad_opus->channels < 3) {

		krad_opus->streams = 1;
		
		if (krad_opus->channels == 2) {
			krad_opus->coupled_streams = 1;
			krad_opus->mapping[0] = 0;
			krad_opus->mapping[1] = 1;			
		} else {
			krad_opus->coupled_streams = 0;		
			krad_opus->mapping[0] = 0;
		}
		
		krad_opus->opus_header->channel_mapping = 0;

	} else {
		krad_opus->opus_header->channel_mapping = 1;

		switch (krad_opus->channels) {
			case 3:
				krad_opus->streams = 2;
				krad_opus->coupled_streams = 1;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 1;
				krad_opus->mapping[2] = 2;
			case 4:
				krad_opus->streams = 2;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 1;
				krad_opus->mapping[2] = 2;
				krad_opus->mapping[3] = 3;				
			case 5:
				krad_opus->streams = 3;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
			case 6:
				krad_opus->streams = 4;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 5;
			case 7:
				krad_opus->streams = 5;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 5;
				krad_opus->mapping[6] = 6;				
			case 8:
				krad_opus->streams = 5;
				krad_opus->coupled_streams = 3;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 6;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 4;
				krad_opus->mapping[6] = 5;
				krad_opus->mapping[7] = 7;				
		}
	}
	
	krad_opus->opus_header->channels = krad_opus->channels;
	krad_opus->opus_header->nb_streams = krad_opus->streams;
	krad_opus->opus_header->nb_coupled = krad_opus->coupled_streams;
	
	memcpy (krad_opus->opus_header->stream_map, krad_opus->mapping, 256);

	krad_opus->encoder = opus_multistream_encoder_create (48000,
														  krad_opus->channels,
														  krad_opus->streams,
														  krad_opus->coupled_streams,
														  krad_opus->mapping,
														  krad_opus->application,
														  &krad_opus->err);

	if (krad_opus->err != OPUS_OK) {
		failfast ("Krad Opus Encoder: Cannot create encoder: %s", opus_strerror (krad_opus->err));
	}
	

	opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_GET_LOOKAHEAD (&krad_opus->lookahead));
	krad_opus->opus_header->preskip = krad_opus->lookahead;

	krad_opus->opus_header->gain = 0;
	krad_opus->opus_header->input_sample_rate = 48000;
	
	if (opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE (krad_opus->bitrate)) != OPUS_OK) {
		failfast ("Krad Opus Encoder: bitrate request failed");
	}

	krad_opus->header_data_size = opus_header_to_packet (krad_opus->opus_header, krad_opus->header_data, 100);
	krad_opus->krad_codec_header.codec = OPUS;
	krad_opus->krad_codec_header.header[0] = krad_opus->header_data;
	krad_opus->krad_codec_header.header_size[0] = krad_opus->header_data_size;
	krad_opus->krad_codec_header.header_combined = krad_opus->header_data;
	krad_opus->krad_codec_header.header_combined_size = krad_opus->header_data_size;
	krad_opus->krad_codec_header.header_count = 2;

	krad_opus->krad_codec_header.header_size[1] = 
	8 + 4 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER=") + strlen (APPVERSION);
	
	krad_opus->opustags_header = calloc (1, krad_opus->krad_codec_header.header_size[1]);
	
	memcpy (krad_opus->opustags_header, "OpusTags", 8);
	
	krad_opus->opustags_header[8] = strlen (opus_get_version_string ());
	
	memcpy (krad_opus->opustags_header + 12, opus_get_version_string (), strlen (opus_get_version_string ()));

	krad_opus->opustags_header[12 + strlen (opus_get_version_string ())] = 1;

	krad_opus->opustags_header[12 + strlen (opus_get_version_string ()) + 4] = strlen ("ENCODER=") + strlen (APPVERSION);
	
	memcpy (krad_opus->opustags_header + 12 + strlen (opus_get_version_string ()) + 4 + 4, "ENCODER=", strlen ("ENCODER="));
	
	memcpy (krad_opus->opustags_header + 12 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER="),
			APPVERSION,
			strlen (APPVERSION));	
	
	krad_opus->krad_codec_header.header[1] = krad_opus->opustags_header;
	
	return krad_opus;

}